1

我想根据发送请求的用户限制表单的查询集。当表单提交但无效时,我无法让 ModelForm 正确限制字段的查询集。表单重新显示错误文本,但查询集不再受限。这可能是什么原因?

模型.py

from django.db import models
from django.contrib.auth.models import User

class Patient(models.Model):
    name = models.CharField(max_length=100)
    doctor = models.ForeignKey(User)
    def __unicode__(self):
        return self.name

class Prescription(models.Model):
    name = models.CharField(max_length=100)
    patient = models.ForeignKey(Patient)

视图.py

import medical.models as models
import medical.forms as forms
from django.shortcuts import render

def add_form(request):
    if request.method == 'POST':
        form = forms.PrescriptionForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = forms.make_prescription_form(request.user)
    return render(request, 'add_form.html', {'form': form})

表格.py

import medical.models as models
from django.forms import ModelForm, ModelChoiceField

class PrescriptionForm(ModelForm):
    class Meta:
        model = models.Prescription

def make_prescription_form(dr):
    class PrescriptionForm(ModelForm):
        patient = ModelChoiceField(queryset=models.Patient.objects.filter(doctor=dr))
        class Meta:
            model = models.Prescription
    return PrescriptionForm

add_form.html

{{ request.user.first_name }}
{% if form.errors %}
<p style="color: red;">Please correct the error{{ form.errors|pluralize }} below.</p>
{% endif %}

<form action="" method="post">{% csrf_token %}
     {{ form }}
     <br>
     <input type="submit" value="Submit">
</form>

我将不胜感激任何帮助,或提出更好的方法来实现同样的事情!让我知道是否有更多文件会有所帮助。我正在使用 Django 1.3。

4

1 回答 1

2

首先,您似乎有点遗漏了 -make_prescription_form返回一个类,而不是表单实例,并且您将类直接传递给 GET 路径中的渲染。我假设这是一个错字。

您没有make_prescription_form在 POST 路径中使用包装器。此实现的最小变化是:

def add_form(request):
    form_class = forms.make_prescription_form(request.user)
    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = form_class()
    return render(request, 'add_form.html', {'form': form})

至于其他方法 - 您可以直接在您的视图中设置表单字段的查询集。

forms.py
class PrescriptionForm(ModelForm):
    class Meta:
        model = models.Prescription

views.py
def add_form(request):
    if request.method == 'POST':
        form = PrescriptionForm(request.POST)
        form.fields['patient'].queryset = models.Patient.objects.filter(doctor=request.user)
        if form.is_valid():
            form.save()
    else:
        form = PrescriptionForm()
        form.fields['patient'].queryset = models.Patient.objects.filter(doctor=request.user)
    return render(request, 'add_form.html', {'form': form})

或设置doctor为 PrescriptionForm 的参数__init__并在那里更新查询集:

forms.py
class PrescriptionForm(ModelForm):
    class Meta:
        model = models.Prescription

    def __init__(self, *args, doctor=None, **kwargs):
        super(PrescriptionForm, self).__init__(*args, **kwargs)
        if self.doctor is not None:
            self.fields['patient'] = models.Patient.objects.filter(doctor=doctor)

views.py
def add_form(request):
    if request.method == 'POST':
        form = PrescriptionForm(request.POST, doctor=request.user)
        if form.is_valid():
            form.save()
    else:
        form = PrescriptionForm(doctor=request.user)
    return render(request, 'add_form.html', {'form': form})                
于 2013-07-24T23:02:40.767 回答