- Author:
- hchargois
- Posted:
- December 11, 2015
- Language:
- Python
- Version:
- 1.7
- Score:
- 0 (after 0 ratings)
Usage :
class MyModelAdmin(ReadonlyLinksMixin, admin.ModelAdmin):
readonly_fields_links = ('field1', 'field2')
This adds a new ModelAdmin property (readonly_fields_links
) that acts like the default readonly_links
except that (if the field's type is a model that can be edited in the admin site) the value of the field has a link to the object.
Same functionality as
Except that it works without messing with the form that gets validated and saved, and thus without sometimes saving None values. It uses the documented property that readonly_fields
can be callables (Django doc) : the fields in readonly_links_fields
are turned into callables that are appended to readonly_links
. Each callable creates the linked value.
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 50 51 52 53 54 55 56 57 | from django.utils.safestring import mark_safe
from django.utils.html import escape
from django.core import urlresolvers
class ReadonlyLinksMixin(object):
@staticmethod
def _make_link_widget(field_name, admin_view):
def link_widget(instance):
field = getattr(instance, field_name)
if field is None:
return "None"
link = urlresolvers.reverse(admin_view, args=(field.id,))
return mark_safe('<a href="%s">%s</a>' % (link, escape(unicode(field))))
return link_widget
def get_readonly_fields(self, request, obj=None):
# get_readonly_fields gets called multiple times and they MUST return EXACTLY the same
# fields because if not Django will break later on when doing some sneaky "let's subtract these fields
# to those fields to see if there's a difference and if I'm missing something"
# Exactly the same fields means, for the callables, that they must be defined only once.
# We thus use some caching/memoization.
try:
return self._link_readonly_fields
except AttributeError:
pass
initial_readonly_fields = super(ReadonlyLinksMixin, self).get_readonly_fields(request, obj)
if not initial_readonly_fields:
initial_readonly_fields = []
link_readonly_fields = []
if hasattr(self, 'readonly_fields_links'):
for field_name in self.readonly_fields_links:
try:
field = getattr(obj, field_name)
app_label = field._meta.app_label
model_name = field._meta.model_name
except AttributeError:
# probably a native type and not a django model,
# let's set it as a normal readonly_field
link_readonly_fields.append(field_name)
continue
admin_view = 'admin:%s_%s_change' % (app_label, model_name)
link_widget = self._make_link_widget(field_name, admin_view)
link_widget.short_description = obj._meta.get_field(field_name).verbose_name
link_readonly_fields.append(link_widget)
if self.exclude is None:
self.exclude = [field_name]
elif field_name not in self.exclude:
self.exclude = list(self.exclude) + [field_name]
link_readonly_fields.extend(initial_readonly_fields)
self._link_readonly_fields = link_readonly_fields
return link_readonly_fields
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Please login first before commenting.