Django manytomany限制

时间:2014-01-25 16:22:12

标签: django django-models django-orm

我是数据库和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

2 个答案:

答案 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