使用get_form()

时间:2018-10-23 16:20:05

标签: python django django-forms django-admin

在ModelAdmin类中覆盖get_form()方法时,即使权限正确,“添加”和“编辑”(加号和铅笔)图标也不会出现在管理页面上的任何字段旁边。删除覆盖的get_form()方法后,图标就会出现。我正在使用表单工厂来渲染ModelForm类,以基于当前用户进行一些查询集过滤,因此我无法在管理员中使用form = <ModelForm>(表单需要捕获HttpRequest对象)

(使用Django 2.1和Python 3.6)

admin.py

@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
    list_display = ('room', 'check_in_date', 'check_out_date', 'guest', 'reserved_by', 'reserved_on')
    inlines = (RoomChangeInline,)


    fieldsets = ( 
    (None, {
        'fields': (
            ('room', 'guest'),
            ('check_in_date', 'check_out_date'),
            ('adults', 'children'),
            ('subtotal', 'taxes', 'deposit'),
            ('reserved_by', 'reserved_on')
        )
    }),)   

    def get_form(self, request, obj=None, **kwargs):
        return reservation_admin_form_factory(request)

forms.py

def reservation_admin_form_factory(request):
    class ReservationAdminForm(forms.ModelForm):
        class Meta: 
            model = Reservation
            exclude = []
            widgets = {
                'check_in_date': forms.DateInput(attrs={'type': 'date'}),
                'check_out_date': forms.DateInput(attrs={'type': 'date'})
            }

        """ I have an __init__() method, but even if I remove it 
        the problem remains, so I am not showing it here. """

    return ReservationAdminForm

1 个答案:

答案 0 :(得分:1)

要在覆盖ModelAdmin的get_form()时在Django admin change_form页面上显示“添加/编辑”按钮,您需要将字段的小部件包装在RelatedFieldWidgetWrapper中,如下所示:

forms.py

from django import forms
from django.conf import settings
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
from django.db.models.fields.reverse_related import ManyToOneRel

def reservation_admin_form_factory(request, admin_site):
    class ReservationAdminForm(forms.ModelForm):
        class Meta:
            model = Reservation
            exclude = []

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            rel = ManyToOneRel(Reservation.guest, Guest, 'id')
            self.fields['guest'].widget = RelatedFieldWidgetWrapper(
                 self.fields['guest'].widget, rel, admin_site, 
                     can_change_related=True)

请注意,以上使用表单工厂(reservation_admin_form_factory)来捕获admin_site需要的RelatedFieldWidgetWrapper对象。

admin.py *

@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
    list_display = ('check_in_date', 'check_out_date')

    def get_form(self, request, obj=None, **kwargs):
        self.form = reservation_admin_form_factory(request, admin.site)
        return super().get_form(request, obj, **kwargs)
相关问题