2013-07-24 5 views
0

Я хочу ограничить набор запросов для формы на основе пользователя, отправляющего запрос. У меня возникли некоторые проблемы с получением ModelForm для правильного ограничения набора запросов в поле при отправке формы, но недействительной. Форма отображается повторно с текстом ошибки, но больше не ограничивается набором запросов. Что может быть причиной здесь?Queryset в 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

Прежде всего, похоже, что вы немного остановились - 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}) 

Что касается других способов сделать это - вы можете просто установить QuerySet поля формы непосредственно на ваш взгляд.

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__ и обновить QuerySet там:

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

Это работало отлично. Спасибо! – Peacemaker636

+0

Кроме того, я хотел, чтобы он возвращал класс формы. Я использую этот же вид для редактирования/добавления нескольких типов объектов. Поэтому у меня есть раздел, в котором он загружает правильный класс в переменную, а затем использует эту переменную для остальной части функции. – Peacemaker636