4

Could you please help me to understand how do limit choices work in the model if it is necessary to limit by field of another model. Currently, I have two models:

Group:

class Group(models.Model):
    name = models.CharField(max_length=10, null=True)
    leader = models.OneToOneField(
        'Student',
        related_name='+',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        limit_choices_to={'group': 2},
    )

and Students:

class Student(models.Model):

    group = models.ForeignKey(Group, on_delete=models.PROTECT)
    name = models.CharField(max_length=140, null=True)
    brd_date = models.DateField(null=True)
    ticket = models.IntegerField(null=True, unique=True)

So as you see every Student has it's group (configured by ForeignKey). But every group may or may not have its own leader. It's just one specific Student (configured by OneToOneField) who is chosen from the group to which he/she actually belongs. Without limiting by Group, it becomes possible to choose every Student as a leader to every group. In the provided Group model I've set limit_choices_to options to limit choices just to the Group 2 (for testing purposes).

Is it possible to set this parameter dynamically and as a result have a possibility of creating Form class based on Group Model in which selection for Group leader allows choosing only students in this particular group?

Thanks in advance.

dimdiden
  • 81
  • 1
  • 10
  • Possible duplicate of http://stackoverflow.com/questions/232435/how-do-i-restrict-foreign-keys-choices-to-related-objects-only-in-django – Rafi Goldfarb Jan 06 '17 at 08:42
  • Thank you for the link. Well yes, there were invented a lot of stuff. However I would be grateful if someone could describe the common approach for solving such puzzle. I like the idea to use an access to students from group like so: object.student_set.all() but is there a clear way to implement a student leader field for Group model? – dimdiden Jan 06 '17 at 20:42

1 Answers1

3

Just want to share the way wich suits me. I just limit my choices using the ModelForm class:

class GroupForm(ModelForm):

    class Meta:
        model = Group
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super(GroupForm, self).__init__(*args, **kwargs)

        self.fields['head'].queryset = Student.objects.filter(group=self.instance)

As you can see with the help of .filter(group=self.instance) I can limit my choices and have a possibility of choosing head from Students who belong only to this particular Group.

Then just:

class UpdateGroup(LoginRequiredMixin, UpdateView):
    model = Group
    form_class = GroupForm

I suppose there is a way to achieve the same result on the model level, but I haven't found it out yet.

dimdiden
  • 81
  • 1
  • 10
  • I doubt there is a way to do it dynamically through limit_choices_to. Maybe through custom [django.db.models.] Manager. – Miloslav Raus May 22 '18 at 10:38
  • A revive: https://docs.djangoproject.com/en/4.1/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to You can now use callable in limit_choices_to. – jacoor Mar 13 '23 at 16:51