user290043
user290043

Reputation:

Django: Form save override

My form:

class AssessmentForm(ModelForm):

    def save(self, commit=True, request=None, *args, **kwargs):

        print 'request.user.id:',request.user.id

        instance = super(AssessmentForm, self).save(commit=False)
        if commit:
            instance.save(request=request)
        if request:
            instance.modifier = request.user
            instance.save(request=request)
        return instance

    class Meta:
        model = Assessment

My Model Class

class Assessment(models.Model):
    name = models.CharField(max_length=255, verbose_name="Title")
    review_state = models.CharField(max_length=20,
                                    choices=REVIEW_STATE_CHOICES)
    iteration = models.IntegerField(choices=ITERATION_CHOICES)
    assessment_note = models.TextField(verbose_name="Notes",
                                       blank=True,
                                       null=True)
    .... snip ....
    modifier = models.ForeignKey(User,
                    editable=False,
                    related_name="%(app_label)s_%(class)s_modifier_related")
    modified = models.DateField(editable=False)


    def save(self, request=None, *args, **kwargs):
        if request:
            user = request.user
        else:
            user = User.objects.get(pk=1)
        self.modifier = user
        self.modified = datetime.now()

        if not self.id:
            self.creator = user
            self.created = datetime.now()
        super(Assessment, self).save(*args, **kwargs)

When I save the form, in the database the modified field has id 1 and not id 5 which is the id of the current user in the user table. So, the save method on the model isn't getting the request but the request is making it to the Form save method which I've tested.... the output of the print statement in the Form save method is:

request.user.id: 5

Updated *

In class AssessmentForm(ModelForm) I've also tried:

def save(self, commit=True, request=None, *args, **kwargs):
    print 'request.user.id:',request.user.id
    instance = super(AssessmentForm, self).save(commit=False)
    if commit:
        instance.save(request=request)
    return instance

Updated 2 ** I just put some print statements in the model save method and I found that there are 3 calls to it. The 1st and 2nd call to it contain the request but the 3rd call does not. So the 1st 2 times the correct user id is saved but the 3rd call wipes it out again. I understand why there are 2 calls to it but why is there a 3rd call?

What am I doing wrong here?

Thx

Upvotes: 3

Views: 4606

Answers (2)

Tommaso Barbugli
Tommaso Barbugli

Reputation: 12031

I think because you are doing 2 wrong things,

1- You expect to have request on the model save method

2- You're doing the (more or less) same things in two different save methods (form and model).

Now you're doing something in the form save and then overriding that in the model save method.

My general suggestion is to drop with request and model save.

It's better to do that kind of validation/checking things at form or view level IMHO.

Upvotes: 2

manji
manji

Reputation: 47978

you're not passing the request object to instance.save()

Upvotes: 7

Related Questions