我是数据库和Django的新手。我对部落的知识很少。
我创建了一个关于学术专家系统的数据库,这里所有论文最多应该包含4个主题。如果选择了更多的主题,则应该将警告称为“太多主题”。很多论文都可以拥有一个主题。所以这是一种多对四的关系。但我不知道如何将上限限制为4。
我的课程是这样的:
class Topic(models.Model):
name = models.CharField(max_length=200)
title = models.CharField(max_length=200)
class Paper(models.Model):
expert = models.ForeignKey(Expert)
topic = models.ManyToManyField('Topic', related_name='topic+', blank=True)
coauthors = models.ManyToManyField('Expert', related_name='coauthors+', blank=True)
title = models.CharField(max_length=200)
citations = models.ManyToManyField('Paper', related_name='citations+', blank=True)
def __str__(self):
return self.title
答案 0 :(得分:2)
我认为您应该在表单提交期间检查数据。尝试将这个重载的clean方法放入表单中,然后将表单放入Paper模型的ModelAdmin定义中。
# admin.py
from django.contrib import admin
from django import forms
from django.core.exceptions import ValidationError
from .models import Paper
class PaperForm(forms.ModelForm):
class Meta:
model = Paper
def clean(self):
topic = self.cleaned_data.get('topic')
if topic.count() > 4:
raise ValidationError("To many topics!")
return self.cleaned_data
class PaperAdmin(admin.ModelAdmin):
form = PaperForm
admin.register(Paper, PaperAdmin)
此外,它不是定义related_name的最佳方式。 related_name应该可以帮助您从它的关系中返回模型。这样做:
# in your model
topics = models.ManyToManyField('Topic', related_name='papers', blank=True)
# shell
paper = Paper.objects.order_by('?')[0] # get random object
paper.topics.all() # and access it's topics
topic = Topic.objects.order_by('?')[0] # now get random topic
topic.papers.all() # and get it's papers using related_name!
这比topic.topic+.all()
好吗?我甚至不确定它是否有效。
答案 1 :(得分:0)
我认为您应该在模型上使用clean()方法,但不要在表单上使用。
首先,因为这是与你的模型有关的东西,而不是你的形式,在某种意义上,如果将来你有其他形式它应该做同样的控制,从而重复你自己。
您可以确定model.clean()方法是Django docs
中表单验证的一部分执行的最好遵循最佳实践(除非你知道更好),并且MVC类似框架之一的最佳实践是fat models