ModelForm中的Queryset最初是适当限制的,但是在提交有错误的表单时则不会

时间:2013-07-24 22:17:02

标签: django django-forms django-1.3

我想根据发送请求的用户限制表单的查询集。我在使用ModelForm在提交表单时正确限制字段的查询集但无效时遇到了一些麻烦。表单将使用错误文本重新显示,但不再限制查询集。这可能是什么原因?

models.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)

views.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})

forms.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。

1 个答案:

答案 0 :(得分:1)

首先,看起来你稍微离开了一点 - make_prescription_form返回一个类,而不是表单实例,并且你将类直接传递给GET路径中的渲染。我假设这是一个错字。

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

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})