Django - 表单试图一起清除唯一性,CrispyError

Django - forms trying to clean unique together, CrispyError

我有一个具有唯一性的模型,我想在我的模型中验证这个条件。唯一一起包括在 init 方法中传递给表单的字段、用户和表单中的字段。我在验证唯一在一起条件时遇到问题。

编辑 我已将代码修改为您在下面看到的内容

型号:

class Objective(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    objective_name = models.CharField(max_length=10)
    description = models.CharField(max_length=300)
    mode = models.CharField(max_length=2, default='LA')

    class Meta:
        unique_together = ['user', 'objective_name', 'course']
        ordering = ['objective_name']

    def __str__(self):
        return self.objective_name

观点:

def addobjective(request, course_id):
    this_course = get_object_or_404(Course, pk=course_id)
    user = request.user
    all_courses = Course.objects.filter(user=user)
    objective_list = Objective.objects.filter(
        course=this_course).order_by('objective_name')
    context = {'objective_list': objective_list}
    if request.method == 'POST':
        form = ObjectiveForm(user, request.POST, my_course=this_course)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.course = this_course
            obj.user = user
            obj.save()
            form = ObjectiveForm(user, my_course=this_course)
            context['form'] = form

            return redirect('gradebook:addobjective', course_id=this_course.id)
    else:
        form = ObjectiveForm(user, my_course=this_course)
        context['form'] = form

    context['this_course'] = this_course
    context['all_courses'] = all_courses

    return render(request, 'gradebook/objective-form.html', context)

forms.py:

class ObjectiveForm(ModelForm):

    def __init__(self, user, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        my_course = kwargs.pop('my_course')
        self.objs = Objective.objects.filter(user=user, course=my_course)
        super(ObjectiveForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Objective
        fields = ('objective_name', 'description', 'mode',)

    def clean(self):
        super(ObjectiveForm, self).clean()
        objective_name = self.cleaned_data.get("objective_name")
        description = self.cleaned_data.get("description")
        mode = self.cleaned_data.get("mode")

        if self.objs.filter(objective_name=objective_name).count() > 0:
            print("error")
            del self.cleaned_data["objective_name"]
            del self.cleaned_data["description"]
            del self.cleaned_data["mode"]
            raise ValidationError(
                "This course already has a learning objective with this name.")

        return self.cleaned_data

编辑

我知道得到的错误是 |as_crispy_field got passed an invalid or inexistent field。当我输入重复的 objective_name 值时会发生这种情况。 error 打印到控制台,然后出现上述错误。我没有得到 ValidationError。 The full traceback can be seen here.

也许我不需要模型中的唯一在一起约束?

是的,my_course 字段未在 Objective 模型中定义,因此您可能需要更改此行:

表格 = Objective表格(request.POST, my_course=this_course)

表格 = Objective表格(request.POST, 课程=this_course)

原来是if form.is_valid():后面的return redirect('gradebook:addobjective', course_id=this_course.id)缩进不当导致的问题。 return 重定向必须是 POST 请求的一部分。