2010-06-09 1 views
10

Я пытаюсь использовать ModelForm для добавления моих данных. Он работает хорошо, за исключением того, что раскрывающийся список ForeignKey показывает все значения, и я хочу, чтобы он отображал значения, которые уместны для зарегистрированного пользователя.Как фильтровать значения в форме Django с помощью ModelForm?

Вот моя модель ExcludedDate, запись я хочу добавить:

class ExcludedDate(models.Model): 
    date = models.DateTimeField() 
    reason = models.CharField(max_length=50) 
    user = models.ForeignKey(User) 
    category = models.ForeignKey(Category) 
    recurring = models.ForeignKey(RecurringExclusion) 

    def __unicode__(self): 
     return self.reason 

Вот модель для той категории, которая является таблица, содержащая отношения, которые я хотел бы ограничить пользователем:

class Category(models.Model): 
    name = models.CharField(max_length=50) 
    user = models.ForeignKey(User, unique=False) 

    def __unicode__(self): 
     return self.name 

И, наконец, код формы:

class ExcludedDateForm(ModelForm): 

    class Meta: 
     model = models.ExcludedDate 
     exclude = ('user', 'recurring',) 

Как получить форму для отображения на Подмножество категорий, где category.user равно зарегистрированному пользователю?

ответ

20

Вы можете настроить форму в инициализации

class ExcludedDateForm(ModelForm): 
    class Meta: 
     model = models.ExcludedDate 
     exclude = ('user', 'recurring',) 
    def __init__(self, user=None, **kwargs): 
     super(ExcludedDateForm, self).__init__(**kwargs) 
     if user: 
      self.fields['category'].queryset = models.Category.objects.filter(user=user) 

И в представлениях, при построении вашей формы, кроме стандартных форм Params, нужно указать также текущий пользователь:

form = ExcludedDateForm(user=request.user) 
+0

Это работало «легко, как пирог!». Я ценю не только ваш ответ, но и полноту вашего ответа. – malandro95

+0

Рад помочь ... –

+0

Итак ... пока форма теперь выглядит великолепно, изменение нарушило представление, которое добавляет данные. Есть идеи? (Код ниже) – malandro95

0

Вот пример:

models.py

class someData(models.Model): 
    name = models.CharField(max_length=100,verbose_name="some value") 

class testKey(models.Model): 
    name = models.CharField(max_length=100,verbose_name="some value") 
    tst = models.ForeignKey(someData) 

class testForm(forms.ModelForm): 
    class Meta: 
     model = testKey 

views.py

... 
.... 
.... 
    mform = testForm() 
    mform.fields["tst"] = models.forms.ModelMultipleChoiceField(queryset=someData.objects.filter(name__icontains="1")) 
... 
... 

Или и может попробовать что-то вроде этого:

class testForm(forms.ModelForm): 
    class Meta: 
     model = testKey 

def __init__(self,*args,**kwargs): 
    super (testForm,self).__init__(*args,**kwargs) 
    self.fields['tst'].queryset = someData.objects.filter(name__icontains="1") 
+1

Это, вероятно, будет работать, но это плохая практика. Вы не должны взламывать форму вне класса формы. Гораздо проще определить эту логику в __init__ –

+0

Да ... Я согласен. Уже обновляю свой пост. – Saff

0

Я знаю, что это старый; но это один из первых результатов поиска Google, поэтому я подумал, что добавлю, как я нашел это.

class CustomModelFilter(forms.ModelChoiceField): 
    def label_from_instance(self, obj): 
     return "%s %s" % (obj.column1, obj.column2) 

class CustomForm(ModelForm): 
    model_to_filter = CustomModelFilter(queryset=CustomModel.objects.filter(active=1)) 

    class Meta: 
     model = CustomModel 
     fields = ['model_to_filter', 'field1', 'field2'] 

Где model_to_filter 'является ForiegnKey модели «CustomModel»

Почему мне нравится этот метод: в «CustomModelFilter» вы можете также изменить путь по умолчанию, объект модели отображается в созданный ChoiceField, как я уже говорил выше.

Смежные вопросы