Django админ разные строки для изменения и добавления представления - PullRequest
13 голосов
/ 10 февраля 2010

Мне нужны отдельные виды для добавления и изменения страницы. На странице добавления я бы хотел исключить некоторые поля из встроенного набора форм. Я подготовил два класса TabularInline, один из которых содержит свойство exclude. Я пытался использовать их следующим образом:

class BoxAdmin(admin.ModelAdmin):
    def change_view(self, request, obj_id):
        self.inlines=[ItemChangeInline,]
        return super(BoxAdmin, self).change_view(self.request, obj_id)
    def add_view(self, request):
        self.inlines=[ItemAddInline,]
        return super(BoxAdmin, self).add_view(self, request)

без эффекта (никакого встроенного не отображается).

Ответы [ 6 ]

17 голосов
/ 24 мая 2013

Работает с Django 1.5+ и выглядит прекрасно и элегантно:

// admin.py
class BoxAdmin(ModelAdmin):

    inlines = ()

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.inlines = (ItemChangeInline, )
        return super(BoxAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.inlines = (ItemAddInline, )
        return super(BoxAdmin, self).add_view(request)

надеюсь, что это может быть полезно для всех

7 голосов
/ 10 февраля 2010

Вот код, который, кажется, работает:

class BoxAdmin(admin.ModelAdmin):
   def change_view(self, request, obj_id):
        self.inlines=[ItemChangeInline,]
        for inline_class in self.inlines:
            inline_instance = inline_class(self.model, self.admin_site)
            self.inline_instances.append(inline_instance)
        return super(BoxAdmin, self).change_view(request, obj_id)
    def add_view(self, request):
        self.inlines=[ItemAddInline,]
        for inline_class in self.inlines:
            inline_instance = inline_class(self.model, self.admin_site)
            self.inline_instances.append(inline_instance)
        return super(BoxAdmin, self).add_view(request)

Однако это выглядит не элегантно, потому что эта часть:

            for inline_class in self.inlines:
            inline_instance = inline_class(self.model, self.admin_site)
            self.inline_instances.append(inline_instance)

является копией-вставкой из init метод admin.ModelAdmin (поэтому он запускается дважды).

1 голос
/ 10 февраля 2010

Почему в add_view у вас есть .add_view(self, request), а в режиме просмотра изменений у вас есть .change_view(self.request, ..)? Я считаю, что вам не нужно self в add_view, так как вы используете super.

0 голосов
/ 31 марта 2019

Вдохновленные вами, ребята, ответьте, Мне удалось добавить больше пользовательских представлений на admin.site.

Много раз, просто хочется add и change страниц с разными настройками, а не реальных дополнительных просмотров

# admin.py
class FooAdmin(admin.ModelAdmin):
    ....
    def edit_tag(self, obj):              # add a Link tag to change-list page
        return mark_safe('<a href="{}?edit=True">Edit</a>'.format(obj.get_absolute_url()))

    edit_tag.short_description = u'Extra Action'

    def change_view(self, request, object_id, form_url='', extra_context=None):
        if request.GET.get('edit', False):
            self.readonly_fields = (
                'total_amount',
            )
            self.inlines = []
        else:
            self.readonly_fields = (
                'name', 'client', 'constructor', 'total_amount'
            )
            self.inlines = [TransactionInline]
        return super(ProjectAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.readonly_fields = (
            'total_amount',
        )
        self.inlines = []
        return super(ProjectAdmin, self).add_view(request)

После этого у меня будет три вида: enter image description here

  1. добавить представление - без встроенного набора форм, нет необходимости добавлять связанные объекты. enter image description here

  2. изменить представление 1 - при встроенном наборе форм, только для добавления встроенных данных (связанных объектов), поле объекта доступно только для чтения enter image description here

  3. изменить вид 2 - без встроенного набора форм, только для изменения объекта. enter image description here

Действительно просто, и мы можем сделать больше, спасибо всем.

0 голосов
/ 29 марта 2016

Еще одно решение для Django 1.3

class BoxAdmin(admin.ModelAdmin):

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.inline_instances = [ItemChangeInline(self.model, self.admin_site)]
        return super(BoxAdmin, self).change_view(request, object_id, extra_context)

    def add_view(self, request, form_url='', extra_context=None):
        self.inline_instances = [ItemAddInline(self.model, self.admin_site)]
        return super(BoxAdmin, self).add_view(request, form_url, extra_context)
0 голосов
/ 15 июня 2014

У меня была ситуация, когда мне нужно было показать Inline на основе сайта администратора, на котором вы работали для данной истории.

Разбираясь с ответом alekwisnia, я смог получить динамические inline, работающие на Django 1.3, используя следующий код:

В основных моментах / admin.py

class HighlightInline(generic.GenericTabularInline):
    model = Highlight
    extra = 1
    max_num = 4
    fields = ('order', 'highlight')
    template = 'admin/highlights/inline.html'

class HighlightAdmin(admin.ModelAdmin):
    def regulate_highlight_inlines(self):
        highlights_enabled = Setting.objects.get_or_default('highlights_enabled', default='')
        highlight_inline_instance = HighlightInline(self.model, self.admin_site)
        highlight_found = any(isinstance(x, HighlightInline) for x in self.inline_instances)
        if highlights_enabled.strip().lower() == 'true':
            if not highlight_found:
                self.inline_instances.insert(0, highlight_inline_instance)
        else:
            if highlight_found:
                self.inline_instances.pop(0)
        print self.inline_instances

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.regulate_highlight_inlines()
        return super(HighlightAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.regulate_highlight_inlines()   
        return super(HighlightAdmin, self).add_view(request, form_url, extra_context)

В истории / admin.py

class StoryAdmin(HighlightAdmin):

Следует отметить, что я не просто манипулирую встроенными классами (HighlightInline), но я изменяю встроенные экземпляры (HighlightInline (self.model, self.admin_site)). Это связано с тем, что django уже создал список встроенных экземпляров на основе списка встроенных классов во время первоначального создания класса admin.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...