2010-05-18 12 views
26

Tengo un formulario de cambio de administrador estándar para un objeto, con los formularios StackedInline habituales para una relación ForeignKey. Me gustaría poder vincular cada elemento en línea a su formulario de cambio de tamaño completo correspondiente, ya que el artículo en línea tiene elementos propios incorporados, y no puedo anidarlos.¿Agregar enlaces a formularios de cambio completo para artículos en línea en django admin?

He intentado de todo, desde widgets personalizados hasta plantillas personalizadas, y no puedo hacer que nada funcione. Hasta ahora, las "soluciones" que he visto en forma de fragmentos simplemente no parecen funcionar para las líneas. Me estoy preparando para probar algunos hacks DOM con jQuery solo para que funcione y continúe.

Espero que me esté faltando algo muy simple, ¡ya que parece una tarea tan simple!

Usando Django 1.2.

+2

he encontrado la respuesta dada en http://stackoverflow.com/questions/2120813 mejor. –

+1

Django> = 1.8, use 'show_change_link' http://stackoverflow.com/a/28170958/3218806 – maxbellec

Respuesta

11

Tuve un problema similar y se me ocurrió un widget personalizado más algunos ajustes al formulario del modelo. Aquí está el widget:

from django.utils.safestring import mark_safe  

class ModelLinkWidget(forms.Widget): 
    def __init__(self, obj, attrs=None): 
     self.object = obj 
     super(ModelLinkWidget, self).__init__(attrs) 

    def render(self, name, value, attrs=None): 
     if self.object.pk: 
      return mark_safe(
       u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' %\ 
         (
         self.object._meta.app_label, 
         self.object._meta.object_name.lower(), 
         self.object.pk, self.object 
         ) 
      ) 
     else: 
      return mark_safe(u'') 

Ahora bien, como Reproductor para cada línea necesita para conseguir diferentes objetos en el constructor no se puede simplemente ponerlo en forma estándar, pero en init método de Forma:

class TheForm(forms.ModelForm): 
    ... 
    # required=False is essential cause we don't 
    # render input tag so there will be no value submitted. 
    link = forms.CharField(label='link', required=False) 

    def __init__(self, *args, **kwargs): 
     super(TheForm, self).__init__(*args, **kwargs) 
     # instance is always available, it just does or doesn't have pk. 
     self.fields['link'].widget = ModelLinkWidget(self.instance) 

Espero que eso ayude.

+0

No he tenido tiempo de probar esto, pero * se ve * como debería funcionar. :) Gracias. –

+1

Esta es una buena solución, se puede hacer aún más fina combinándola con http://stackoverflow.com/questions/5197280/for-a-django-model-how-can-i-get-the-django- admin-url-to-add-another-or-list-o –

+2

Además, esto puede ser vulnerable a los ataques XSS (dependiendo de los objetos presentados y de dónde vienen), y realmente no los quiere en el administrador - - renderiza la cadena con una plantilla de Django en lugar del% de python. –

42

he hecho algo como lo siguiente en mi admin.py:

from django.utils.html import format_html 
from django.core.urlresolvers import reverse 

class MyModelInline(admin.TabularInline): 
    model = MyModel 

    def admin_link(self, instance): 
     url = reverse('admin:%s_%s_change' % (instance._meta.app_label, 
               instance._meta.module_name), 
         args=(instance.id,)) 
     return format_html(u'<a href="{}">Edit</a>', url) 
     # … or if you want to include other fields: 
     return format_html(u'<a href="{}">Edit: {}</a>', url, instance.title) 

    readonly_fields = ('admin_link',) 
+0

He agregado esto a mi administrador pero no veo el enlace. La columna ha sido añadida aunque ¿Algunas ideas? –

+1

Buena solución. Muy limpio – freb

+1

Esta debería ser la mejor respuesta, si funciona. – dspjm

0

pienso: args = [instance.id] deben ser args = [instance.pk]. ¡Funcionó para mí!

2

respuesta de Quentin arriba funciona, pero también es necesario especificar campos = ('ADMIN_LINK',)

45

Hay una propiedad llamada show_change_link desde Django 1.8.

+1

¡debería ser la mejor respuesta! – rix

+0

¿Por qué este no es un top? – kotrfa

1

La solución actualmente aceptada aquí es un buen trabajo, pero está desactualizada.

Desde Django 1.3, hay una propiedad incorporada llamada show_change_link = True que resuelve este problema.

Esto se puede agregar a cualquier objeto StackedInline o TabularInline. Por ejemplo:

class ContactListInline(admin.TabularInline): 
    model = ContactList 
    fields = ('name', 'description', 'total_contacts',) 
    readonly_fields = ('name', 'description', 'total_contacts',) 
    show_change_link = True 

El resultado será algo esta línea:

tabular inline using show_change_link

+0

Pero, ¿y si quiero que un título sea un hipervínculo, pero no una etiqueta al lado del título? – adkl

Cuestiones relacionadas