【问题标题】:can't override default admin model form django无法覆盖默认管理模型表单 django
【发布时间】:2011-01-24 08:02:21
【问题描述】:

我需要在 Admin 中为我的 DateField 添加额外的验证,以确保给定的日期是将来的。我没有这方面的经验,所以这就是我所做的。 1) 我创建了自定义表单字段并为其添加了验证:

class PastDateField(forms.DateField):
    def clean(self, value):
    """Validates if only date is in the past
    """
        if not value:
            raise forms.ValidationError('Plase enter the date')
        if value > datetime.now():
            raise forms.ValidationError('The date should be in the past, not in future')
        return value

2) 然后我添加了自定义模型表单:

class CustomNewsItemAdminForm(forms.ModelForm):
    title = forms.CharField(max_length=100)
    body = forms.CharField(widget=forms.Textarea)
    date = PastDateField()
    region = forms.ModelChoiceField(Region.objects)

3) 以下是我注册管理员的方式:

class NewsItemAdmin(admin.ModelAdmin):
    form = CustomNewsItemAdminForm

    def queryset(self, request):
        return NewsItem.objects.all()

admin.site.register(NewsItem, NewsItemAdmin)

这样做的结果是我的管理表单 1) 显示我没有在自定义管理表单中指定的字段 2) 日期时间字段缺少 JavaScript 日历

对我来说很明显我做错了什么,但我没有找到与我的需求相关的示例,因为我是菜鸟。向日期时间字段添加自定义验证而不搞砸的更好方法是什么?

编辑:非常感谢 Brian Luft 和 Daniel Roseman 的正确回答!为了使这篇文章对面临同样问题的人有所帮助,这里是生成的代码:

class CustomNewsItemAdminForm(forms.ModelForm):
    class Meta:
        model = NewsItem

    def clean_date(self):
        """Validates if only date is in the past
        """
        date = self.cleaned_data["date"]
        if date is None:
            raise forms.ValidationError('Plase enter the date')
        if date > datetime.now().date():
            raise forms.ValidationError('The date should be in the past, not in future')
        return self.cleaned_data["date"]

class NewsItemAdmin(admin.ModelAdmin):
    form = CustomNewsItemAdminForm

    def queryset(self, request):
        return NewsItem.objects.all()

admin.site.register(NewsItem, NewsItemAdmin)

【问题讨论】:

标签: django django-models django-admin validation


【解决方案1】:

首先,在 ModelForm 上显式声明字段 - 无论是在管理员内部还是外部 - 并不意味着不会显示其他字段。您需要在表单的内部 Meta 类中定义 fieldsexclude 元组。如果其他字段都是默认的,您可以简单地声明您要覆盖的字段。

其次,如果您希望自定义字段使用 javascript,则需要使用正确的小部件,即 django.contrib.admin.widgets.AdminDateWidget。但是,有一种更简单的方法可以做到这一点,它根本不定义自定义字段,而是在表单本身上定义 clean_date 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 2014-01-05
    • 2017-01-27
    • 2022-01-11
    • 2010-11-19
    • 1970-01-01
    相关资源
    最近更新 更多