djangodjango-formsdjango-views

Django update a model form


I have a modelform:

class UserPreferencesForm(ModelForm):
    """
    Form for storing user preferences.
    """
    class Meta:
        model = UserPreferences
        exclude = ('user')

the model:

class UserPreferences(models.Model):
    """
    Model for user project preferences.
    """
    user = models.OneToOneField(User)
    ...

and in the views:

    ...
    form = UserPreferencesForm(request.POST or None)
    if form.is_valid():
        # save the form
        prefs = form.save(commit=False)
        prefs.user = request.user
        prefs.update()
        messages.add_message(
            request, messages.INFO, 'Your preferences have been updated.'
        )
    ...

I want to ensure that each user only has one set of preferences, so I would like to refactor the view code to use something along the lines of the update() model method instead of checking for object existence and then saving, which would incur more queries.

What is the most efficient way of 'create-or-updating' the model?


Solution

  • Are you interested in saving the query to detect if a row exists?

    In the case, you could do as you describe.. do an update and check if 0 rows were updated, which implies the profile doesn't exist.

    updated = Preferences.objects.filter(user=request.user).update(**form.cleaned_data)
    if updated == 0:
        # create preference object
    

    But an even simpler design pattern is to ensure there is always a preferences table for every user via a signal listening on models.signals.post_save sent by the User class.

    Then, you can assume it always exists.

    def create_prefs(sender, instance, created, **kwargs):
         if created:
             # create prefs
    
    models.signals.post_save.connect(create_prefs, sender=User)