Django

Code

Changeset 8265

Show
Ignore:
Timestamp:
08/09/08 11:45:15 (5 months ago)
Author:
jacob
Message:

Broke the admin's use of LogEntry? and user messages out into callbacks on ModelAdmin?. Refs #6002.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/admin/options.py

    r8245 r8265  
    263263 
    264264    def __call__(self, request, url): 
    265         # Check that LogEntry, ContentType and the auth context processor are installed. 
    266265        from django.conf import settings 
    267266        if settings.DEBUG: 
    268             from django.contrib.admin.models import LogEntry 
    269             if not LogEntry._meta.installed: 
    270                 raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.") 
    271             if not ContentType._meta.installed: 
    272                 raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.") 
    273             if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: 
    274                 raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") 
     267            self.check_dependancies() 
    275268 
    276269        # Delegate to the appropriate method, based on the URL. 
     
    286279            return self.change_view(request, unquote(url)) 
    287280 
     281    def check_dependancies(self): 
     282        """ 
     283        Check that all things needed to run the admin have been correctly installed. 
     284         
     285        The default implementation checks that LogEntry, ContentType and the 
     286        auth context processor are installed. 
     287        """ 
     288        from django.conf import settings 
     289        from django.contrib.admin.models import LogEntry 
     290         
     291        if not LogEntry._meta.installed: 
     292            raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.") 
     293        if not ContentType._meta.installed: 
     294            raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.") 
     295        if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: 
     296            raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") 
     297 
    288298    def _media(self): 
    289299        from django.conf import settings 
     
    360370        for inline in self.inline_instances: 
    361371            yield inline.get_formset(request, obj) 
    362  
    363     def save_add(self, request, form, formsets, post_url_continue): 
    364         """ 
    365         Saves the object in the "add" stage and returns an HttpResponseRedirect. 
    366  
    367         `form` is a bound Form instance that's verified to be valid
     372             
     373    def log_addition(self, request, object): 
     374        """ 
     375        Log that an object has been successfully added.  
     376         
     377        The default implementation creates an admin LogEntry object
    368378        """ 
    369379        from django.contrib.admin.models import LogEntry, ADDITION 
    370         opts = self.model._meta 
    371         new_object = form.save(commit=True) 
    372  
    373         if formsets: 
    374             for formset in formsets: 
    375                 # HACK: it seems like the parent obejct should be passed into 
    376                 # a method of something, not just set as an attribute 
    377                 formset.instance = new_object 
    378                 formset.save() 
    379  
    380         pk_value = new_object._get_pk_val() 
    381         LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), ADDITION) 
    382         msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)} 
    383         # Here, we distinguish between different save types by checking for 
    384         # the presence of keys in request.POST. 
    385         if request.POST.has_key("_continue"): 
    386             request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) 
    387             if request.POST.has_key("_popup"): 
    388                 post_url_continue += "?_popup=1" 
    389             return HttpResponseRedirect(post_url_continue % pk_value) 
    390  
    391         if request.POST.has_key("_popup"): 
    392             return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \ 
    393                 # escape() calls force_unicode. 
    394                 (escape(pk_value), escape(new_object))) 
    395         elif request.POST.has_key("_addanother"): 
    396             request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 
    397             return HttpResponseRedirect(request.path) 
    398         else: 
    399             request.user.message_set.create(message=msg) 
    400             # Figure out where to redirect. If the user has change permission, 
    401             # redirect to the change-list page for this object. Otherwise, 
    402             # redirect to the admin index. 
    403             if self.has_change_permission(request, None): 
    404                 post_url = '../' 
    405             else: 
    406                 post_url = '../../../' 
    407             return HttpResponseRedirect(post_url) 
    408     save_add = transaction.commit_on_success(save_add) 
    409  
    410     def save_change(self, request, form, formsets=None): 
    411         """ 
    412         Saves the object in the "change" stage and returns an HttpResponseRedirect. 
    413  
    414         `form` is a bound Form instance that's verified to be valid. 
    415  
    416         `formsets` is a sequence of InlineFormSet instances that are verified to be valid. 
     380        LogEntry.objects.log_action( 
     381            user_id         = request.user.pk,  
     382            content_type_id = ContentType.objects.get_for_model(object).pk, 
     383            object_id       = object.pk, 
     384            object_repr     = force_unicode(object),  
     385            action_flag     = ADDITION 
     386        ) 
     387         
     388    def log_change(self, request, object, message): 
     389        """ 
     390        Log that an object has been successfully changed.  
     391         
     392        The default implementation creates an admin LogEntry object. 
    417393        """ 
    418394        from django.contrib.admin.models import LogEntry, CHANGE 
    419         opts = self.model._meta 
    420         new_object = form.save(commit=True) 
    421         pk_value = new_object._get_pk_val() 
    422  
    423         if formsets: 
    424             for formset in formsets: 
    425                 formset.save() 
    426  
    427         # Construct the change message. 
     395        LogEntry.objects.log_action( 
     396            user_id         = request.user.pk,  
     397            content_type_id = ContentType.objects.get_for_model(object).pk,  
     398            object_id       = object.pk,  
     399            object_repr     = force_unicode(object),  
     400            action_flag     = CHANGE,  
     401            change_message  = message 
     402        ) 
     403         
     404    def log_deletion(self, request, object, object_repr): 
     405        """ 
     406        Log that an object has been successfully deleted. Note that since the 
     407        object is deleted, it might no longer be safe to call *any* methods 
     408        on the object, hence this method getting object_repr. 
     409         
     410        The default implementation creates an admin LogEntry object. 
     411        """ 
     412        from django.contrib.admin.models import LogEntry, DELETION 
     413        LogEntry.objects.log_action( 
     414            user_id         = request.user.id,  
     415            content_type_id = ContentType.objects.get_for_model(self.model).pk,  
     416            object_id       = object.pk,  
     417            object_repr     = object_repr, 
     418            action_flag     = DELETION 
     419        ) 
     420         
     421     
     422    def construct_change_message(self, request, form, formsets): 
     423        """ 
     424        Construct a change message from a changed object. 
     425        """ 
    428426        change_message = [] 
    429427        if form.changed_data: 
     
    446444                                             'object': deleted_object}) 
    447445        change_message = ' '.join(change_message) 
    448         if not change_message: 
    449             change_message = _('No fields changed.') 
    450         LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), CHANGE, change_message) 
     446        return change_message or _('No fields changed.') 
     447     
     448    def message_user(self, request, message): 
     449        """ 
     450        Send a message to the user. The default implementation  
     451        posts a message using the auth Message object. 
     452        """ 
     453        request.user.message_set.create(message=message) 
     454 
     455    def save_add(self, request, form, formsets, post_url_continue): 
     456        """ 
     457        Saves the object in the "add" stage and returns an HttpResponseRedirect. 
     458 
     459        `form` is a bound Form instance that's verified to be valid. 
     460        """ 
     461        opts = self.model._meta 
     462        new_object = form.save(commit=True) 
     463 
     464        if formsets: 
     465            for formset in formsets: 
     466                # HACK: it seems like the parent obejct should be passed into 
     467                # a method of something, not just set as an attribute 
     468                formset.instance = new_object 
     469                formset.save() 
     470 
     471        pk_value = new_object._get_pk_val() 
     472        self.log_addition(request, new_object) 
     473                 
     474        msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)} 
     475        # Here, we distinguish between different save types by checking for 
     476        # the presence of keys in request.POST. 
     477        if request.POST.has_key("_continue"): 
     478            self.message_user(request, msg + ' ' + _("You may edit it again below.")) 
     479            if request.POST.has_key("_popup"): 
     480                post_url_continue += "?_popup=1" 
     481            return HttpResponseRedirect(post_url_continue % pk_value) 
     482 
     483        if request.POST.has_key("_popup"): 
     484            return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \ 
     485                # escape() calls force_unicode. 
     486                (escape(pk_value), escape(new_object))) 
     487        elif request.POST.has_key("_addanother"): 
     488            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 
     489            return HttpResponseRedirect(request.path) 
     490        else: 
     491            self.message_user(request, msg) 
     492 
     493            # Figure out where to redirect. If the user has change permission, 
     494            # redirect to the change-list page for this object. Otherwise, 
     495            # redirect to the admin index. 
     496            if self.has_change_permission(request, None): 
     497                post_url = '../' 
     498            else: 
     499                post_url = '../../../' 
     500            return HttpResponseRedirect(post_url) 
     501    save_add = transaction.commit_on_success(save_add) 
     502 
     503    def save_change(self, request, form, formsets=None): 
     504        """ 
     505        Saves the object in the "change" stage and returns an HttpResponseRedirect. 
     506 
     507        `form` is a bound Form instance that's verified to be valid. 
     508 
     509        `formsets` is a sequence of InlineFormSet instances that are verified to be valid. 
     510        """ 
     511        opts = self.model._meta 
     512        new_object = form.save(commit=True) 
     513        pk_value = new_object._get_pk_val() 
     514 
     515        if formsets: 
     516            for formset in formsets: 
     517                formset.save() 
     518         
     519        change_message = self.construct_change_message(request, form, formsets) 
     520        self.log_change(request, new_object, change_message)         
    451521 
    452522        msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)} 
    453523        if request.POST.has_key("_continue"): 
    454             request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) 
     524            self.message_user(request, msg + ' ' + _("You may edit it again below.")) 
    455525            if request.REQUEST.has_key('_popup'): 
    456526                return HttpResponseRedirect(request.path + "?_popup=1") 
     
    458528                return HttpResponseRedirect(request.path) 
    459529        elif request.POST.has_key("_saveasnew"): 
    460             request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}) 
     530            msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object} 
     531            self.message_user(request, msg) 
    461532            return HttpResponseRedirect("../%s/" % pk_value) 
    462533        elif request.POST.has_key("_addanother"): 
    463             request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 
     534            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 
    464535            return HttpResponseRedirect("../add/") 
    465536        else: 
    466             request.user.message_set.create(message=msg) 
     537            self.message_user(request, msg) 
    467538            return HttpResponseRedirect("../") 
    468539    save_change = transaction.commit_on_success(save_change) 
     
    650721    def delete_view(self, request, object_id, extra_context=None): 
    651722        "The 'delete' admin view for this model." 
    652         from django.contrib.admin.models import LogEntry, DELETION 
    653723        opts = self.model._meta 
    654724        app_label = opts.app_label 
     
    679749            obj_display = str(obj) 
    680750            obj.delete() 
    681             LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, object_id, obj_display, DELETION) 
    682             request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)}) 
     751             
     752            self.log_deletion(request, obj, obj_display) 
     753            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)}) 
     754             
    683755            if not self.has_change_permission(request, None): 
    684756                return HttpResponseRedirect("../../../../")