Built-in save_model method

Hi there,
I wonder if it is a good practice to override the save model method or if there is a cleaner way to achieve the following:

  • to create a user and add other fields in my customerUser model.
  • to update a user role field in the admin section

My current solution is based on calling a function to update the role of my user.
but I have this error message : Model instances passed to related filters must be saved.
The user is not created yet so the function can’t check the role of the user and set the role of the user.

Given that I thought that the only way to nake that happen is that

class CustomUserAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # Save the CustomUser instance before calling update_user_role
        obj.save()
        # Call my update_user_role function with the saved instance
        update_user_role(obj, obj.is_manager, obj.is_customer)
        # and complete the default save_model behavior
        super().save_model(request, obj, form, change)

Will it work? any recommendations to achieve that.
Thanks

It is. It’s why it is documented as an interface for that purpose.

Certainly looks like it will.

There’s no way to know if there’s a better way to do it without seeing update_user_role and your Custom User model.

Side note: When posting code here, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted. (I’ve taken the liberty of fixing your original post for you.)

thanks your prompt answer!

#role_service
"""
Update the user role profile is_expert is_customer is_manager
"""
from .models import Expert
import datetime

def update_user_role (user, is_expert, is_customer):
#raise error if both roles are selected.    
    if is_expert and is_customer:
        raise ValueError("You can't set both is_customer and is_manager")
#if user is no longer an expert remove instance
#check the user role profile is_expert is_customer 
    if is_expert: 
        expert_instance, created = Expert.objects.get_or_create(user=user)
        #then if created add the start_date and save
        if created:
            expert_instance.start_date = datetime.date.today()
            expert_instance.save()
    else:
        Expert.objects.filter(user=user).delete()    

Model:

class CustomUser(AbstractUser):
    location = models.CharField(max_length=200, null=True, blank=True)
    name = models.CharField(max_length=200, blank=True, null=True)

    is_customer = models.BooleanField(default=False)
    is_expert = models.BooleanField(default=False)
    is_manager = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

For what you have defined, what you’ve got is fine.

I’m a little confused by the (possible) distinction between is_expert and is_manager, since your update_user_role is using the name is_expert, but the save_model method is passing is_manager.

It does seem like you’re storing redundant data. If you’ve got an Expert object related to the user to indicate that they are an expert or manager (or both?), having a separate is_expert field would be redundant.

for is_manager that’s okay because I am still editing the code
Thank you, you answer my question.