ManyToMany字段上的Django-admin验证

时间:2016-06-16 10:48:19

标签: python django validation django-models django-admin

我有一个django模型,我有一个Module类,可以将字段'sort'设置为4个值之一(Video,Article,Quiz,Test)。如果选择了视频或文章,那么我已经进行了验证,以确保字段'textfile'(上传的文件)不为空。我想验证如果选择了测验或测试,那么至少还会添加一个问题。您可以在下面的类模块中看到我尝试过的验证,但它不起作用。

这是models.py:

class Question(models.Model):
    name = models.CharField(max_length=500, verbose_name="Question")
    QUESTION_TYPE = (
        ('Multi', 'Multiple Choice (one correct answer)'),
        ('Check', 'Multiple Answers'),
        ('Matched', 'Match Responses on left with answers on right'),
    )
    sort = models.CharField(
        default="Multi",
        max_length=7,
        verbose_name = "Question Type",
        choices = QUESTION_TYPE)
    answer = models.ManyToManyField(
        Answer,
        through         = 'QuestionAnswer',
        related_name    = 'answer',
        verbose_name    = 'Answer',
        help_text       = 'Answers to this Question'
        )

    def __unicode__(self):
        return u'%s' % (self.name)


class Module(models.Model):
    name = models.CharField(verbose_name='Module Title', max_length=50)
    MODULE_TYPE = (
        ('Video', 'Video'),
        ('Quiz', 'Quiz'),
        ('Article', 'Article'),
        ('Test','Test')
    )
    sort = models.CharField(
        verbose_name='Module Content',
        default="Video",
        max_length=7,
        choices = MODULE_TYPE)
    textfile = models.ForeignKey(DataFile, blank=True, null=True, verbose_name='Data File' )
    description = models.TextField(blank=True, null=True, verbose_name='Module Description')    
    weight = models.IntegerField(default=0, verbose_name="Module Weighting", help_text="Provide the weight you want this module to carry in the course final score.")
    question = models.ManyToManyField(
        Question,
        through         = 'ModuleQuestions',
        related_name    = 'question',
        verbose_name    = 'Question',
        help_text       = 'Questions in this Module'
        )

    def __unicode__(self):
        return u'%s' % (self.name)

    def clean (self):
        if self.sort in ['Video','Article']:
            if not self.textfile:
                 raise ValidationError(
                    _("Videos and Articles must have an linked Data File"),
                    )
        if self.sort in ['Quiz','Test']:
            if not self.question :
                raise ValidationError (
                    _("Quiz and Test Modules must have at least 1 Question"),
                )

class ModuleQuestions(models.Model):
    module = models.ForeignKey(
        Module,
        verbose_name    = 'Module',
        help_text       = 'Module is part of a Course.',
    )
    question = models.ForeignKey(
        Question,
        verbose_name    = 'Question',
        help_text       = 'Quiz and Test Modules have Questions allocated to them.',
    )       
    order = models.IntegerField(
        verbose_name    = 'Order',
        help_text       = 'The order the Questions are presented to the student',
    )

这是我的admin.py

class ModuleQuestionsInline(admin.TabularInline):
    model = ModuleQuestions
    extra = 1

class ModuleAdmin(admin.ModelAdmin):
    inlines = (ModuleQuestionsInline,)

class QuestionAnswerInline(admin.TabularInline):
    model = QuestionAnswer
    extra = 1


class QuestionAdmin(admin.ModelAdmin):
    inlines = (QuestionAnswerInline,)


admin.site.register(Module, ModuleAdmin)
admin.site.register(Question, QuestionAdmin)

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

https://groups.google.com/d/msg/django-users/f_MKyPg_C4w/0WMJol1atOoJ

  

基本上,你不能。保存模型后保存M2m字段,   所以你要么得到尚未准备好进行检查的对象(如   你经历过)或者你将测试m2m字段的先前值,   这两者都不是你想要的。

     

您可以修改管理界面并在中进行验证   AdminForm,或者可能捕获m2m_changed信号并进行一些检查   那里,但你不能在干净的方法中进行你想要的验证。