Apostolos
Apostolos

Reputation: 8101

ModelForms ForeignKeys and Django

I have an app that has the following models

models.py
class Student (models.Model):
    first_name = models.CharField(max_length=40, default='')
    second_name = models.CharField(max_length=40, default='')
    #more fields here

class Paper (models.Model):
    #more fields here
    student = models.ForeignKey(Student)

class StudentPayment(models.Model):
    student = models.ForeignKey(Student)
    paper = models.ForeignKey(Paper)

and i have created my ModelForms for adding new student and Papers in very simple way

#forms.py
class StudentForm(forms.ModelForm):
    class Meta:
        model = Student

class PaperForm(forms.ModelForms):
    class Meta:
        model = Paper

class StudentPaymentForm(forms.ModelForms):
    class Meta:
        model = StudentPayment

A student pays for a specific paper. I use the ModelForms to generate a form to add a student a paper or a payment. When the StudentPaymentForm is created the select field for paper contains all papers that were added in the database. Is there a way to make the paper select field contain the papers only for a specific chosen student (from the student select field) or is it a jquery(or ajax) task?

Upvotes: 0

Views: 153

Answers (2)

knbk
knbk

Reputation: 53649

Django will create a default ModelChoiceField for the student attribute. It is possible to alter the queryset of a ModelChoiceField. The best way would probably be in the __init__ method of your form:

class StudentPaymentForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        student_queryset = kwargs.pop('paper_queryset', None)
        super(StudentPaymentForm, self).__init__(*args, **kwargs)
        if self.instance:
            self.fields['paper'].queryset = self.instance.student.paper_set.all()
        elif paper_queryset:
            self.fields['paper'].queryset = paper_queryset

This will only allow papers related to the specific student instance. However, it won't magically update your choices when you select another student, you'll need Ajax/jQuery for that. You will, however, get a validation error when you select a paper that doesn't belong to the student you've selected, and you will have the updated options for the student you've selected once you try to submit the form (and it returns with an error).

Upvotes: 2

goromlagche
goromlagche

Reputation: 442

I think running a query like

context['paper'] = Paper.objects.filter(student=self.request.user)

and then pass the context to the form will help.

Upvotes: 0

Related Questions