首页 > 解决方案 > 如何将参数传递给 QueryDicts 并将其连续传递给要在其中使用的 django 表单

问题描述

描述: 我正在使用 django 表单Completed_Exercise为那些使用ModelForm类成功完成确定练习的用户填写模型实例,但是由于 aCompleted_ExerciseForm有三个字段,其中两个对应于 ForeignKey 字段,我不需要将它们呈现在模板上,但得分为一(有趣的是,用户可以进行自我限定),所以我决定通过副本将它们作为参数传递给ModelForm实例。request.GET

我用谷歌搜索了一个小时并尝试并纠正了一些东西......但即便如此我也犯了同样的错误,据我所知,这也可以通过将它们作为 kwargs 传递给表单来完成,但这不是预期的方式。非常感谢任何帮助。

结果: 我无法从表单内部访问 QueryDict

楷模:

class Completed_Exercise(models.Model):

    possible_scores = list(zip(range(1,8), range(1,8)))
    exercise = models.OneToOneField(Exercise, default=None, on_delete=models.CASCADE)
    points = models.IntegerField(default=0, choices=possible_scores)
    student = models.ForeignKey('accounts.Student', on_delete = models.CASCADE, related_name='completed_exercises')
    
    def __str__(self):
        return self.name

#Student belongs to other django app, despite its placed alongside the first one. 
class Student(models.Model):
    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE, related_name="student")
    pui = models.CharField(max_length=20, blank=True, default='')
    grade = models.CharField(max_length=1, blank=True, default='')
    score = models.IntegerField(default=0)
    reputation = models.IntegerField(default=0)

    def __str__(self):
        return self.user.username

看法:

def exercise_detail_view(request,pk):
    
    form = Completed_ExerciseForm()
    exercise = get_object_or_404(Exercise, pk=pk)

    if request.method == "GET":
        if request.user.is_authenticated:
            copy = request.GET.copy()
            
            copy['student'] = request.user.student
            copy['exercise'] = get_object_or_404(Exercise, pk=pk)
            form = Completed_ExerciseForm(copy)
            print(copy)
            print('you are registered...glad am i')
        else:
            return redirect('login')

        if request.user.student.completed_exercises.filter(pk=pk).exists():
            messages.add_message(request, messages.ERROR, 'You are done with that exercise already')
            print('exercise_completed!!!')
            return redirect('exercise/' + str(pk))

        elif form.is_valid():

            form.save()
            print('saved the holy form')
            return redirect(request.META['HTTP-REFERER'])
   
    
    context = { 'exercise':exercise, 'form':form }
    return render(request, 'training/exercise.html',context=context)

形式:

class Completed_ExerciseForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.qQ = args[0]
        super().__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        Completed_Exercise.objects.create(student = self.qQ['student'], exercise = self.qQ['exercise'], points = self.points)

    class Meta:
        model = Completed_Exercise
        fields = ['points']

这是我得到的错误

我认为这足以回答,如果不是这样,请告诉我。

标签: pythondjango

解决方案


使用 aModelForm您可以提供initial关键字参数,该参数是表单将加载的键和值的字段名称的字典。我也不会那样覆盖save()

因此,在您的情况下,要使用这些值定义那些 FK 字段,您可以执行以下操作;

class Completed_ExerciseForm(forms.ModelForm):
    
    class Meta:
        model = Completed_Exercise
        fields = [
            'points',
            'student',
            'exercise'
        ]
        widgets = {
            'student': forms.HiddenInput(),
            'exercise': forms.HiddenInput(),
        }

def exercise_detail_view(request,pk):
    
    form = Completed_ExerciseForm()
    exercise = get_object_or_404(Exercise, pk=pk)

    if request.method == "GET":
        if request.user.is_authenticated:
            initial = {}
            initial['student'] = request.user.student
            initial['exercise'] = get_object_or_404(Exercise, pk=pk)
            form = Completed_ExerciseForm(initial=initial)
            print(initial)
            print('you are registered...glad am i')
        else:
            return redirect('login')

推荐阅读