Login

Creator/updater fields for admin

Author:
baumer1122
Posted:
July 21, 2008
Language:
Python
Version:
.96
Tags:
admin newforms-admin
Score:
0 (after 0 ratings)

This ModelAdmin class sets fields for models saved in admin corresponding to the user that created the object and the user that last updated the object. Trivial for the current model, but a little more involved to make it work with inlines.

The fields still show up as drop-downs (select) in the admin, but I fixed that with a little jQuery:

$(function(){
    $("select[id*='creator'], select[id*='updater']").each(function(){
        var user = $('option:selected', this).text();
        $(this).siblings('.add-another').hide();
        $(this).hide();
        $(this).after(user);
    });
});

This could easily be subverted, but with trusted users, it makes for a quick and dirty read-only field.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#name of User foreign key fields to log object creator and last updater
CREATE_USER_FIELD = 'creator'
UPDATE_USER_FIELD = 'updater'

class CreatorUpdaterAdmin(admin.ModelAdmin):
    def save_add(self, request, form, formsets, post_url_continue):
        """
        Set `CREATE_USER_FIELD` to admin user that created the record
        """
        #check main form
        if form.cleaned_data.has_key(CREATE_USER_FIELD):
            form.cleaned_data[CREATE_USER_FIELD] = request.user
            
        #check inlines
        for formset in formsets:
            for cleaned_data in formset.cleaned_data:
                if cleaned_data.has_key(CREATE_USER_FIELD):
                    cleaned_data[CREATE_USER_FIELD] = request.user
        
        return super(CreatorUpdaterAdmin, self).save_add(request, form, formsets, post_url_continue)
    
    def save_change(self, request, form, formsets):
        """
        Set `UPDATE_USER_FIELD` to admin user that updated the record
        """
        #check main form
        if form.cleaned_data.has_key(UPDATE_USER_FIELD):
            form.cleaned_data[UPDATE_USER_FIELD] = request.user
            
        #check inlines
        for formset in formsets:
            for cleaned_data in formset.cleaned_data:
                pk_name = formset.model._meta.pk.attname
                pk_value = cleaned_data.get(pk_name, False)
                #if it doesn't have an primary key value, it is being created
                if not pk_value and cleaned_data.has_key(CREATE_USER_FIELD):
                    cleaned_data[CREATE_USER_FIELD] = request.user
                    
                #inlines get resubmitted on every save, so we need to check if the
                #form differs from the value in the database before setting the
                #UPDATE_USER_FIELD
                elif cleaned_data.has_key(UPDATE_USER_FIELD):
                    model_dict = cleaned_data.copy()
                    del model_dict['DELETE']
                    try:
                        formset.model.objects.get(**model_dict)
                    except formset.model.DoesNotExist:
                        cleaned_data[UPDATE_USER_FIELD] = request.user
        return super(CreatorUpdaterAdmin, self).save_change(request, form, formsets)

More like this

  1. Admin Hack: Quick lookup of GenericForeignKey id by ContentType by adnan 6 years, 5 months ago
  2. FieldLevelPermissionsAdmin by buriy 7 years, 5 months ago
  3. Generic views with row-level permission handling by mwicat 3 years, 10 months ago
  4. Full Model History by willhardy 6 years, 2 months ago
  5. Friendly ID by willhardy 6 years, 2 months ago

Comments

carljm (on July 22, 2008):

Nice idea.

Instead of the jQuery, why not just mark the fields editable=False? If you want the values still visible in the admin, you can override change_form.html for that model and add text display of the fields.

#

johnboxall (on August 4, 2008):

Be careful here!

save_add is called after add_view. add_view calls form.is_valid(). This means that you will have to set your CREATE_USER_FIELD with blank=True otherwise you'll get errors about not settings the User field!

#

Please login first before commenting.