diff options
| author | Unai Zalakain <unai@gisa-elkartea.org> | 2013-10-24 17:28:09 +0200 |
|---|---|---|
| committer | Simon Charette <charette.s@gmail.com> | 2013-10-29 17:10:12 -0400 |
| commit | fd219fa24c7911adab60e1f5e4fd3d7f9d82a969 (patch) | |
| tree | bebe575f54927599841c3be976eccfeeb7d84e49 /django | |
| parent | 497930b7f69e2c298faa3f784c4523ea351e5e6f (diff) | |
Fixed #8261 -- ModelAdmin hook for customising the "show on site" button
``ModelAdmin.view_on_site`` defines wether to show a link to the object on the
admin detail page. If ``True``, cleverness (i.e. ``Model.get_absolute_url``) is
used to get the url. If it's a callable, the callable is called with the object
as the only parameter. If ``False``, not link is displayed.
With the aim of maitaining backwards compatibility, ``True`` is the default.
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/admin/helpers.py | 8 | ||||
| -rw-r--r-- | django/contrib/admin/options.py | 18 | ||||
| -rw-r--r-- | django/contrib/admin/templates/admin/change_form.html | 2 | ||||
| -rw-r--r-- | django/contrib/admin/templates/admin/edit_inline/stacked.html | 2 | ||||
| -rw-r--r-- | django/contrib/admin/templates/admin/edit_inline/tabular.html | 2 | ||||
| -rw-r--r-- | django/contrib/admin/validation.py | 5 |
6 files changed, 30 insertions, 7 deletions
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 622664fc6b..5bc19872e9 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -202,9 +202,10 @@ class InlineAdminFormSet(object): def __iter__(self): for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()): + view_on_site_url = self.opts.get_view_on_site_url(original) yield InlineAdminForm(self.formset, form, self.fieldsets, self.prepopulated_fields, original, self.readonly_fields, - model_admin=self.opts) + model_admin=self.opts, view_on_site_url=view_on_site_url) for form in self.formset.extra_forms: yield InlineAdminForm(self.formset, form, self.fieldsets, self.prepopulated_fields, None, self.readonly_fields, @@ -242,13 +243,14 @@ class InlineAdminForm(AdminForm): A wrapper around an inline form for use in the admin system. """ def __init__(self, formset, form, fieldsets, prepopulated_fields, original, - readonly_fields=None, model_admin=None): + readonly_fields=None, model_admin=None, view_on_site_url=None): self.formset = formset self.model_admin = model_admin self.original = original if original is not None: self.original_content_type_id = ContentType.objects.get_for_model(original).pk - self.show_url = original and hasattr(original, 'get_absolute_url') + self.show_url = original and view_on_site_url is not None + self.absolute_url = view_on_site_url super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields, readonly_fields, model_admin) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index fe5b5e0edf..e3514dd82a 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -98,6 +98,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)): formfield_overrides = {} readonly_fields = () ordering = None + view_on_site = True # validation validator_class = validation.BaseValidator @@ -243,6 +244,19 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)): return db_field.formfield(**kwargs) + def get_view_on_site_url(self, obj=None): + if obj is None or not self.view_on_site: + return None + + if callable(self.view_on_site): + return self.view_on_site(obj) + elif self.view_on_site: + # use the ContentType lookup if view_on_site is True + return reverse('admin:view_on_site', kwargs={ + 'content_type_id': ContentType.objects.get_for_model(obj).pk, + 'object_id': obj.pk + }) + @property def declared_fieldsets(self): warnings.warn( @@ -971,6 +985,7 @@ class ModelAdmin(BaseModelAdmin): app_label = opts.app_label preserved_filters = self.get_preserved_filters(request) form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url) + view_on_site_url = self.get_view_on_site_url(obj) context.update({ 'add': add, 'change': change, @@ -978,7 +993,8 @@ class ModelAdmin(BaseModelAdmin): 'has_change_permission': self.has_change_permission(request, obj), 'has_delete_permission': self.has_delete_permission(request, obj), 'has_file_field': True, # FIXME - this should check if form or formsets have a FileField, - 'has_absolute_url': hasattr(self.model, 'get_absolute_url'), + 'has_absolute_url': view_on_site_url is not None, + 'absolute_url': view_on_site_url, 'form_url': form_url, 'opts': opts, 'content_type_id': ContentType.objects.get_for_model(self.model).id, diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html index 1acfcd37db..79ea73933c 100644 --- a/django/contrib/admin/templates/admin/change_form.html +++ b/django/contrib/admin/templates/admin/change_form.html @@ -32,7 +32,7 @@ {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %} <a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a> </li> - {% if has_absolute_url %}<li><a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%} + {% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%} {% endblock %} </ul> {% endif %}{% endif %} diff --git a/django/contrib/admin/templates/admin/edit_inline/stacked.html b/django/contrib/admin/templates/admin/edit_inline/stacked.html index 42f68f3f97..0fa81ef597 100644 --- a/django/contrib/admin/templates/admin/edit_inline/stacked.html +++ b/django/contrib/admin/templates/admin/edit_inline/stacked.html @@ -6,7 +6,7 @@ {% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}"> <h3><b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span> - {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %} + {% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% trans "View on site" %}</a>{% endif %} {% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %} </h3> {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %} diff --git a/django/contrib/admin/templates/admin/edit_inline/tabular.html b/django/contrib/admin/templates/admin/edit_inline/tabular.html index 94be6f89b9..2a3463280d 100644 --- a/django/contrib/admin/templates/admin/edit_inline/tabular.html +++ b/django/contrib/admin/templates/admin/edit_inline/tabular.html @@ -27,7 +27,7 @@ <td class="original"> {% if inline_admin_form.original or inline_admin_form.show_url %}<p> {% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %} - {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %} + {% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% trans "View on site" %}</a>{% endif %} </p>{% endif %} {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %} {{ inline_admin_form.fk_field.field }} diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py index 84f8b67e4d..0023d13f3b 100644 --- a/django/contrib/admin/validation.py +++ b/django/contrib/admin/validation.py @@ -164,6 +164,11 @@ class BaseValidator(object): for idx, f in enumerate(val): get_field(cls, model, "prepopulated_fields['%s'][%d]" % (field, idx), f) + def validate_view_on_site_url(self, cls, model): + if hasattr(cls, 'view_on_site'): + if not callable(cls.view_on_site) and not isinstance(cls.view_on_site, bool): + raise ImproperlyConfigured("%s.view_on_site is not a callable or a boolean value." % cls.__name__) + def validate_ordering(self, cls, model): " Validate that ordering refers to existing fields or is random. " # ordering = None |
