0

我有一个Detail模型,它有一个ForeignKey()模型User。我想在模板的前端显示与单个用户关联的列表subject(这是模型的一个字段)。Detail它应该是一个下拉菜单,用户应该能够从列表中选择主题并提交表单。

我应该如何完成它?

下面是我的models.py

class Detail(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.CharField(max_length=50)
    skype_session_attendance = models.FloatField()
    internal_course_marks = models.FloatField()
    programming_lab_activity = models.FloatField()
    mid_term_marks = models.FloatField()
    final_term_marks = models.FloatField()

    def __str__(self):
        return f'{self.subject, (self.user.username)} Details'

以下是我的views.py:

def performanceCalculator(request):
    if request.method == 'POST':
        performance_form = PerformanceCalculatorForm(request.POST, user=request.user)

        if performance_form.is_valid():
            sub = performance_form.cleaned_data['subject']

            detail = Detail.objects.all().filter(user=request.user, subject=sub).first()

            result = fuzz_algo(detail.skype_session_attendance,
                detail.internal_course_marks, detail.programming_lab_activity,
                detail.mid_term_marks, detail.final_term_marks)

            messages.success(request, result)

            return redirect('performance_calculator')
    else:
        performance_form = PerformanceCalculatorForm(user=request.user)

    context = {
        'performance_form': performance_form,        
    }

    return render(request, 'users/performance_calculator.html', context)

下面是forms.py:

class PerformanceCalculatorForm(forms.Form):
    subject = # what should I put here in order to make a dropdown list?

    class Meta:
        fields = ['subject']

下面是views.py中PerformanceCalculatorForm的更新代码:

class PerformanceCalculatorForm(forms.Form):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(PerformanceCalculatorForm, self).__init__(*args, **kwargs)
        self.fields['subject'].queryset = Detail.objects.filter(user=user)

    subject = forms.ModelChoiceField(queryset=None)

    class Meta:
        fields = ['subject']
4

1 回答 1

1

你不需要把它放在这里

class PerformanceCalculatorForm(forms.Form):
    subject = # what should I put here in order to make a dropdown list?

    class Meta:
        fields = ['subject']

https://docs.djangoproject.com/en/3.0/ref/models/fields/#choices上有片段

相反,在你的 models.py 上做

class Detail(models.Model):
    #create your choice tuple
    SUBJECT_CHOICES = [
        #(actual value on database, human readable text)
        ('math','Math'),
        ('algebra1', 'Algebra I'),
        ('calculus3','Calculus III'),
    ]

    user = models.ForeignKey(User, on_delete=models.CASCADE)
                                              #here add the choices
    subject = models.CharField(max_length=50, choices=SUBJECT_CHOICES)
    skype_session_attendance = models.FloatField()
    internal_course_marks = models.FloatField()
    programming_lab_activity = models.FloatField()
    mid_term_marks = models.FloatField()
    final_term_marks = models.FloatField()

    def __str__(self):
        return f'{self.subject, (self.user.username)} Details'

通过将元组传递给选择值,它将在渲染上用选择框替换。


与动态添加选择到模型字段相关的更新: 更好和实用的方法是使用一个函数来返回每个主题并将其附加到您的选择列表中。

在你的 models.py 中保留它像以前一样。

class Detail(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.CharField(max_length=50)
    skype_session_attendance = models.FloatField()
    internal_course_marks = models.FloatField()
    programming_lab_activity = models.FloatField()
    mid_term_marks = models.FloatField()
    final_term_marks = models.FloatField()

    def __str__(self):
        return f'{self.subject, (self.user.username)} Details'

对于您评论的问题,您可以将它返回__str__给您喜欢的任何内容,但使用特殊字符将其分隔,然后这将在 POST 请求中看到并split()用于让您subject退出查询集对象。

__str__您的模型中:

    return f'{self.user.username}-{self.subject}'

现在在你的views.py中使用split()你想要匹配的部分

def performanceCalculator(request):
    if request.method == 'POST':
        performance_form = PerformanceCalculatorForm(request.POST, user=request.user)

        if performance_form.is_valid():
            sub = performance_form.cleaned_data['subject']
            sub = str(sub).split('-')[1] #user-subject will get the subject part

            detail = Detail.objects.all().filter(user=request.user, subject=sub).first()

            result = fuzz_algo(detail.skype_session_attendance,
                detail.internal_course_marks, detail.programming_lab_activity,
                detail.mid_term_marks, detail.final_term_marks)

            messages.success(request, result)

            return redirect('performance_calculator')
    else:
        performance_form = PerformanceCalculatorForm(user=request.user)

    context = {
        'performance_form': performance_form,        
    }

    return render(request, 'users/performance_calculator.html', context)
于 2020-05-15T15:06:17.337 回答