views:

93

answers:

3

In one of my Django models, I override the save function. I do this to get the user's username. But that keeps failing.

this is what i did:

    def save(self, *args, **kwargs):
    self.slug = slugify('%s' % (self.question))
    if not self.id:
        self.publish_date = datetime.datetime.now()
        self.publisher = self.request.user
    self.modification_date = datetime.datetime.now()
    self.modifier = self.request.user
    super(Faq, self).save(*args, **kwargs) # Call the "real" save() method

This fails with: 'Faq' object has no attribute 'request'

Thanks.

+1  A: 

request is only passed to views, not model methods so you will have to set the publisher in a view.

I would remove the line self.modifier = self.request.user from here and set modifier = request.user at the same time as you set question which I assume you are doing in a view.

Then you can change self.publisher = self.request.user to self.publisher = self.modifier

Hope that helps.

Jake
Thanks Jake. The problem there is that this is from the Admin section.
Eric
+1  A: 

You'll need to pass the request into the save method since it doesn't exist in that context automatically.

def save(self, request, *args, **kwargs):
    self.slug = slugify('%s' % (self.question))
    if not self.id:
        self.publish_date = datetime.datetime.now()
        self.publisher = request.user
    self.modification_date = datetime.datetime.now()
    self.modifier = self.request.user
    super(Faq, self).save(*args, **kwargs) # Call the "real" save() method

Usage...

my_faq = Faq()
my_faq.save(request)
Adam
Adam, this is done from the Admin section. So, I don't think I have the option to send the request along with the call.
Eric
+3  A: 

If this is for use within the Admin app, as you say in your answer to Jake, then you shouldn't override the model save method at all. Instead, you should override the save_model method of the ModelAdmin class.

See the original code in django.contrib.admin.options - you'll see that it's already passed the request object. So all you need to do is to assign the publisher there:

def save_model(self, request, obj, form, change):
    obj.slug = slugify('%s' % (obj.question))
    if not obj.id:
        obj.publish_date = datetime.datetime.now()
        obj.publisher = request.user
    obj.modification_date = datetime.datetime.now()
    obj.modifier = request.user
    obj.save()
Daniel Roseman
Thank you Daniel, for pointing this out! :) And, for providing the solution. Just for my understanding, save_model method at the end calls. obj.save(). That call to save is the one that is specified in model.py. Yes? Thanks to everybody who responded. :)
Eric
Actually, I went ahead and tested it... In save_model override, I just have the line obj.save(request) and the save override in models.py I changed from self.request.user to request.user. This worked nicely. So, should I ever save from a view, I will have the functionality that I want. :) Again, thanks.
Eric
I would modify your model save method override so that it can work even if it's not given a request, that way you cover yourself for future changes. `def save(self, request=None, *args, **kwargs):` `if request: ...`
Jake
Great, Jake, thanks for the suggestion. Clearly a better solution than what I had. :)
Eric