Ticket #2901: admin_log_with_site.2.diff
File admin_log_with_site.2.diff, 10.0 KB (added by , 18 years ago) |
---|
-
django/views/defaults.py
24 24 if absurl.startswith('http://'): 25 25 return http.HttpResponseRedirect(absurl) 26 26 27 # Try to figure out the related site for the object 27 28 object_domain = None 29 site = Site.objects.get_for_obj(obj) 30 if site: 31 object_domain = site.domain 28 32 29 # Otherwise, we need to introspect the object's relationships for a30 # relation to the Site object31 opts = obj._meta32 33 # First, look for an many-to-many relationship to sites34 for field in opts.many_to_many:35 if field.rel.to is Site:36 try:37 object_domain = getattr(obj, field.name).all()[0].domain38 except IndexError:39 pass40 if object_domain is not None:41 break42 43 # Next look for a many-to-one relationship to site44 if object_domain is None:45 for field in obj._meta.fields:46 if field.rel and field.rel.to is Site:47 try:48 object_domain = getattr(obj, field.name).domain49 except Site.DoesNotExist:50 pass51 if object_domain is not None:52 break53 54 33 # Fall back to the current site (if possible) 55 34 if object_domain is None: 56 35 try: -
django/contrib/sites/models.py
2 2 from django.utils.translation import gettext_lazy as _ 3 3 4 4 class SiteManager(models.Manager): 5 5 6 def get_current(self): 6 7 from django.conf import settings 7 8 return self.get(pk=settings.SITE_ID) 8 9 10 def get_for_object(self, obj): 11 """ 12 Returns the Site object for the given model object, if that object has 13 a corresponding relation. Otherwise it returns None. 14 """ 15 opts = obj._meta 16 17 # First, look for an many-to-many relationship to sites 18 for field in opts.many_to_many: 19 if field.rel.to is Site: 20 if getattr(obj, field.name): 21 try: 22 return getattr(obj, field.name).all()[0] 23 except IndexError: 24 pass 25 26 # Next look for a many-to-one relationship to sites 27 for field in obj._meta.fields: 28 if field.rel and field.rel.to is Site: 29 return getattr(obj, field.name) 30 31 # Cannot determine a direct relation to sites, so return None 32 return None 33 9 34 class Site(models.Model): 10 35 domain = models.CharField(_('domain name'), maxlength=100) 11 36 name = models.CharField(_('display name'), maxlength=50) -
django/contrib/admin/templatetags/log.py
1 1 from django import template 2 from django.conf import settings 2 3 from django.contrib.admin.models import LogEntry 4 from django.db import models 3 5 4 6 register = template.Library() 5 7 6 8 class AdminLogNode(template.Node): 7 def __init__(self, limit, varname, user): 8 self.limit, self.varname, self.user = limit, varname, user 9 def __init__(self, limit, varname, user, site): 10 self.limit = limit 11 self.varname = varname 12 self.user = user 13 self.site = site 9 14 10 15 def __repr__(self): 11 16 return "<GetAdminLog Node>" … … 13 18 def render(self, context): 14 19 if self.user is not None and not self.user.isdigit(): 15 20 self.user = context[self.user].id 16 context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit] 21 22 entries = LogEntry.objects.filter(user__id__exact=self.user) 23 if self.site: 24 if not self.site.isdigit(): 25 self.site = context[self.site].id 26 entries = entries.filter(models.Q(site__id=self.site) | 27 models.Q(site__id__isnull=True)) 28 29 context[self.varname] = entries.select_related()[:self.limit] 17 30 return '' 18 31 19 32 class DoGetAdminLog: … … 23 36 Usage:: 24 37 25 38 {% get_admin_log [limit] as [varname] for_user [context_var_containing_user_obj] %} 39 40 or:: 26 41 42 {% get_admin_log [limit] as [varname] for_site [context_var_containing_site_obj] %} 43 27 44 Examples:: 28 45 29 46 {% get_admin_log 10 as admin_log for_user 23 %} 30 {% get_admin_log 10 as admin_log for_user user %} 47 {% get_admin_log 10 as admin_log for_user varname %} 48 {% get_admin_log 10 as admin_log for_site %} 49 {% get_admin_log 10 as admin_log for_site 2 %} 50 {% get_admin_log 10 as admin_log for_site varname %} 31 51 {% get_admin_log 10 as admin_log %} 32 52 33 53 Note that ``context_var_containing_user_obj`` can be a hard-coded integer 34 54 (user ID) or the name of a template context variable containing the user 35 object whose ID you want. 55 object whose ID you want. The ``context_var_containing_site_obj`` works the 56 same way, except that when you omit a value, it uses the current site. 36 57 """ 37 58 def __init__(self, tag_name): 38 59 self.tag_name = tag_name … … 45 66 raise template.TemplateSyntaxError, "First argument in '%s' must be an integer" % self.tag_name 46 67 if tokens[2] != 'as': 47 68 raise template.TemplateSyntaxError, "Second argument in '%s' must be 'as'" % self.tag_name 69 user = site = None 48 70 if len(tokens) > 4: 49 if tokens[4] != 'for_user': 50 raise template.TemplateSyntaxError, "Fourth argument in '%s' must be 'for_user'" % self.tag_name 51 return AdminLogNode(limit=tokens[1], varname=tokens[3], user=(len(tokens) > 5 and tokens[5] or None)) 71 if tokens[4] not in ('for_user', 'for_site'): 72 raise template.TemplateSyntaxError, "Fourth argument in '%s' must be 'for_user' or 'for_site'" % self.tag_name 73 if tokens[4] == 'for_user': 74 user = len(tokens) > 5 and tokens[5] or None 75 else: 76 site = len(tokens) > 5 and tokens[5] or str(settings.SITE_ID) 77 return AdminLogNode(limit=tokens[1], varname=tokens[3], user=user, site=site) 52 78 53 79 register.tag('get_admin_log', DoGetAdminLog('get_admin_log')) -
django/contrib/admin/models.py
1 1 from django.db import models 2 2 from django.contrib.contenttypes.models import ContentType 3 3 from django.contrib.auth.models import User 4 from django.contrib.sites.models import Site 4 5 from django.utils.translation import gettext_lazy as _ 5 6 6 7 ADDITION = 1 … … 8 9 DELETION = 3 9 10 10 11 class LogEntryManager(models.Manager): 11 def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''): 12 e = self.model(None, None, user_id, content_type_id, object_id, object_repr[:200], action_flag, change_message) 12 def log_action(self, user, model, obj, action, message=''): 13 site_id = None 14 site = Site.objects.get_for_object(obj) 15 if site: 16 site_id = site.id 17 e = self.model(None, None, user.id, site_id, 18 ContentType.objects.get_for_model(model).id, 19 obj._get_pk_val(), str(obj)[:200], action, message) 13 20 e.save() 14 21 15 22 class LogEntry(models.Model): 16 23 action_time = models.DateTimeField(_('action time'), auto_now=True) 17 24 user = models.ForeignKey(User) 25 site = models.ForeignKey(Site, blank=True, null=True) 18 26 content_type = models.ForeignKey(ContentType, blank=True, null=True) 19 27 object_id = models.TextField(_('object id'), blank=True, null=True) 20 28 object_repr = models.CharField(_('object repr'), maxlength=200) -
django/contrib/admin/views/main.py
253 253 if not errors: 254 254 new_object = manipulator.save(new_data) 255 255 pk_value = new_object._get_pk_val() 256 LogEntry.objects.log_action(request.user .id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), ADDITION)256 LogEntry.objects.log_action(request.user, model, new_object, ADDITION) 257 257 msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object} 258 258 # Here, we distinguish between different save types by checking for 259 259 # the presence of keys in request.POST. … … 340 340 change_message = ' '.join(change_message) 341 341 if not change_message: 342 342 change_message = _('No fields changed.') 343 LogEntry.objects.log_action(request.user .id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message)343 LogEntry.objects.log_action(request.user, model, new_object, CHANGE, change_message) 344 344 345 345 msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object} 346 346 if request.POST.has_key("_continue"): … … 507 507 raise PermissionDenied 508 508 obj_display = str(obj) 509 509 obj.delete() 510 LogEntry.objects.log_action(request.user .id, ContentType.objects.get_for_model(model).id, object_id, obj_display, DELETION)510 LogEntry.objects.log_action(request.user, model, obj, DELETION) 511 511 request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display}) 512 512 return HttpResponseRedirect("../../") 513 513 extra_context = {