Подтвердить что ты не робот

Django Admin встроенный встроенный

Мне нужен встроенный администратор django admin, который я могу включить в поле даты в строке другого, как показано ниже.

У меня есть следующие модели:

class Person(models.Model):
     name = models.CharField(max_length=200)
     id_no = models.IntegerField()

class Certificate(models.Model):
     cerfificate_no = models.CharField(max_length=200)
     certificate_date = models.DateField(max_length=100)
     person = models.ForeignKey(Person)
     training = models.CharField(max_length=200)

class Training_Date(models.Model):
      date = models.DateField()
      certificate = models.ForeignKey(Certificate)

и admin ниже:

class CertificateInline(admin.StackedInline):
    model = Certificate

class PersonAdmin(admin.ModelAdmin):
     inlines = [CertificateInline,]
admin.site.register(Person,PersonAdmin)

но мне нужно включить модель Training_Date как встроенную, которая является частью встроенного сертификата.

Любая идея?

4b9b3361

Ответ 1

AFAIK, вы не можете иметь второй уровень встроенных строк в admin Django по умолчанию.

Администратор Django - это просто нормальное приложение Django, поэтому ничто не мешает вам реализовать второй уровень вложенных форм, но IMHO это будет своего рода запутанный дизайн для реализации. Возможно, поэтому для этого нет никаких положений.

Ответ 2

В последнее время было какое-то движение в https://code.djangoproject.com/ticket/9025, но я бы не задерживал дыхание.

Один общий способ - связать администратор между первым и вторым (или вторым и третьим) уровнем, имея как ModelAdmin, так и Inline для той же модели:

Дайте сертификат ModelAdmin с помощью TrainingDate как встроенного. Дайте CertificateInline дополнительное поле "Сведения", которое является ссылкой на форму изменения ModelAdmin.

models.py:

from django.core import urlresolvers

class Certificate(models.Model):

    # ...

    def changeform_link(self):
        if self.id:
            # Replace "myapp" with the name of the app containing
            # your Certificate model:
            changeform_url = urlresolvers.reverse(
                'admin:myapp_certificate_change', args=(self.id,)
            )
            return u'<a href="%s" target="_blank">Details</a>' % changeform_url
        return u''
    changeform_link.allow_tags = True
    changeform_link.short_description = ''   # omit column header

admin.py:

# Certificate change form has training dates as inline

class TrainingDateInline(admin.StackedInline):
    model = TrainingDate

class CertificateAdmin(admin.ModelAdmin):
    inlines = [TrainingDateInline,]
admin.site.register(Certificate ,CertificateAdmin)

# Person has Certificates inline but rather
# than nesting inlines (not possible), shows a link to
# its own ModelAdmin change form, for accessing TrainingDates:

class CertificateLinkInline(admin.TabularInline):
    model = Certificate
    # Whichever fields you want: (I usually use only a couple
    # needed to identify the entry)
    fields = ('cerfificate_no', 'certificate_date', 'changeform_link')
    readonly_fields = ('changeform_link', )

class PersonAdmin(admin.ModelAdmin):
    inlines = [CertificateLinkInline,]
admin.site.register(Person, PersonAdmin)

Ответ 3

Более универсальное решение

from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse
class EditLinkToInlineObject(object):
    def edit_link(self, instance):
        url = reverse('admin:%s_%s_change' % (
            instance._meta.app_label,  instance._meta.model_name),  args=[instance.pk] )
        if instance.pk:
            return mark_safe(u'<a href="{u}">edit</a>'.format(u=url))
        else:
            return ''

class MyModelInline(EditLinkToInlineObject, admin.TabularInline):
    model = MyModel
    readonly_fields = ('edit_link', )

class MySecondModelAdmin(admin.ModelAdmin):
    inlines = (MyModelInline, )

admin.site.register(MyModel)
admin.site.register(MySecondModel, MySecondModelAdmin)

Ответ 4

pip install django-nested-inline

Этот пакет должен делать то, что вам нужно.

Ответ 6

Я использовал решение, предоставленное @bigzbig (спасибо).

Я также хотел вернуться на первую страницу списка после сохранения изменений, поэтому добавил:

class MyModelInline(EditLinkToInlineObject, admin.TabularInline):
    model = MyModel
    readonly_fields = ('edit_link', )

    def response_post_save_change(self, request, obj):
        my_second_model_id = MyModel.objects.get(pk=obj.pk).my_second_model_id
        return redirect("/admin/mysite/mysecondmodel/%s/change/" % (my_second_model_id))