无法覆盖 django 的默认管理模型

发布于 2024-08-24 19:27:57 字数 1927 浏览 4 评论 0原文

我需要在管理中向我的日期字段添加额外的验证,以确保给定的日期是将来的日期。我没有这方面的经验,所以这就是我所做的。 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)

I need to add extra validation to my DateField in Admin to make sure the date given is in the future. I have no experience in such a thing, so here's what I've done.
1) I've created custom form field and added validation to it:

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) Then I've added custom model form:

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

3) And here's how I've registered admin:

class NewsItemAdmin(admin.ModelAdmin):
    form = CustomNewsItemAdminForm

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

admin.site.register(NewsItem, NewsItemAdmin)

The result of this is that my admin form
1) Shows field I haven't specified in custom admin form
2) Lacks JavaScript calendar for the datetime field

It's pretty obvious to me that I'm doing something wrong, but I've found no examples relevant to my needs as I am a noob. What is the better way to add custom validation to datetime field without messing things up?

EDIT: Thanks a lot to Brian Luft and Daniel Roseman for correct answers! To make this post helpful for someone facing the same problem here is the resulting code:

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

源来凯始玺欢你 2024-08-31 19:27:57

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

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

Firstly, declaring fields explicitly on a ModelForm - whether in or out of the admin - does not mean that the other fields will not be displayed. You need to define the fields or exclude tuples in the form's inner Meta class. If the other fields are all the default, you can simply declare the one you are overriding.

Secondly, if you want your custom field to use the javascript, you'll need to use the right widget, which is django.contrib.admin.widgets.AdminDateWidget. However, there is a much easier way to do this, which is not define a custom field at all, but instead define a clean_date method on the form itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文