overriding save_form in an Admin doesn't work for an inline'd Admin

+4 votes
asked Nov 11, 2010 by kevin

I override save_form to automatically populate the author field in class Grievances by using obj.author = request user. Works great. But then, for purposes of the inline, I try the same thing using obj.status_author = request.user. Doesn't work - nothing is input and the sql execution fails because status_author is a required field.

The successful overriding of save_form takes place in my GrievancesAdmin for obj.author. If I try the same thing for obj.status_author, but in GrievanceStatusAdmin (which gets inlined), it does not work as nothing in input.

I have the following files:

models.py

class Grievances(models.Model): title = models.CharField(max_length=90) author = models.ForeignKey(User, related_name='grievance_author') firefighter = models.ForeignKey(User, related_name='firefighter_harmed') ...
class GrievanceStatus(models.Model): title = models.ForeignKey(Grievances) updatetext = models.TextField(blank=True) action = models.CharField(max_length=20) status_author = models.ForeignKey(User, related_name='grievance_status_author')

forms.py

class UserModelChoiceField(forms.ModelChoiceField): """ Override to use full name in ChoiceField """ def label_from_instance(self, obj): return "%s (%s)" % (obj.get_full_name(), obj.username)
class GrievanceForm(forms.ModelForm): firefighter = UserModelChoiceField(User.objects.all().order_by('last_name')) class Meta: model = Grievances
class GrievanceStatusForm(forms.ModelForm): class Meta: model = GrievanceStatus fields = ('action', 'updatetext', )

admin.py

class GrievanceStatusInline(admin.StackedInline): model = GrievanceStatus fk_name = 'title' form = GrievanceStatusForm list_select_related = True
class GrievancesAdmin(admin.ModelAdmin): list_display = ('title', 'firefighter',) inlines = [ GrievanceStatusInline ] form = GrievanceForm def save_formset(self, request, form, formset, change): ### something is wrong with the following line but i'm not sure what ### obj2 = super(GrievancesAdmin, self).save_formset(request, form, formset, change) obj2.status_author = request.user formset.save() def save_form(self, request, form, change): obj = super(GrievancesAdmin, self).save_form(request, form, change) obj.firefighter = User.objects.get(username__exact=obj.firefighter) obj.status_author = request.user if not change: obj.author = request.user obj.date_updated = datetime.datetime.now() return obj
admin.site.register(Grievances, GrievancesAdmin)

Thanks!

2 Answers

+2 votes
answered Nov 11, 2010 by bernhard-vallant

You should try something like the following! I put a try...except block there because you may have other forms on the page as well, that don't have a status_author attribute!

class GrievancesAdmin(admin.ModelAdmin): def save_formset(self, request, form, formset, change): formset.save() if not change: for f in formset.forms: try: obj = f.instance obj.status_author = request.user obj.save() except: continue
0 votes
answered Nov 29 by daniel-roseman

For an inline admin, you probably want to override save_formset instead.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
...