Python Django admin在使用get_form()时缺少添加/编辑按钮
在ModelAdmin类中重写Python Django admin在使用get_form()时缺少添加/编辑按钮,python,django,django-forms,django-admin,Python,Django,Django Forms,Django Admin,在ModelAdmin类中重写get_form()方法时,“添加”和“编辑”(加号和铅笔)图标不会出现在管理页面上的任何字段旁边,即使权限正确。当我删除覆盖的get\u form()方法时,图标就会出现。我正在使用表单工厂呈现ModelForm类,以便根据当前用户执行一些queryset筛选,因此我无法在管理中使用form=(表单需要捕获HttpRequest对象) (使用Django 2.1和Python 3.6) admin.py @admin.register(Reservation) c
get_form()
方法时,“添加”和“编辑”(加号和铅笔)图标不会出现在管理页面上的任何字段旁边,即使权限正确。当我删除覆盖的get\u form()
方法时,图标就会出现。我正在使用表单工厂呈现ModelForm类,以便根据当前用户执行一些queryset筛选,因此我无法在管理中使用form=
(表单需要捕获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)
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
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)
forms.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)
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
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)
要在覆盖ModelAdmin的
get\u form()
时显示Django admin change\u form页面上的添加/编辑按钮,需要将字段的小部件包装在RelatedFieldWidgetWrapper
中,如下所示:
forms.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)
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
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\u admin\u form\u factory
)来捕获admin\u站点
对象,这是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)
如果您只是在
ReservationAdmin
中说form=ReservationAdminForm
并删除get\u form()
方法(而不是使用表单工厂),是否会发生同样的情况,我看到管理员更改表单上出现了预期的按钮。可能原始的get\u表单
返回一个表单,指向一些HTML字段模板,其中包括这些按钮?谢谢Raydel。根据您的建议,我查看了get_form()的源代码。该方法调用modelform\u factory(),它接受多个参数,关键参数是formfield\u callback
。因此,我的新代码看起来是这样的(抱歉,无法在注释中获得正确的格式,因此我使用了pastebin):好的,这不起作用。最初,它似乎在工作,正如图标所示,但事实上Django正在完成忽略我的自定义ModelForm
对象。修复方法是在RelatedFieldWidgetWrapper
调用中包装字段的小部件(参见答案)。这对我来说几乎是可行的。只是弹出窗口不会打开,而是加载到当前选项卡/页面中。事实上,我正在使用一个修改过的版本作为dajngo管理操作的中间页面,该操作带有一个自定义模板。我还尝试在模板中添加{{form.media}
,因为我认为弹出窗口是使用JS调用的。但这对我也不起作用。