4

I have a model structure along those lines:

# models.py
class Foo(models.Model):
    ...

class Bar(models.Model):
    foo = models.ForeignKey(Foo)
    ...

class Baz(models.Model):
    bar = models.ForeignKey(Bar)
    ...

Now, on the DetailView for Foo instances, I have a link to create Baz instances that belong to the Foo instance (via one of its Bar instances). That Link points to the following CreateView:

class BazCreateView(CreateView):
    model = Baz
    fields = ['bar', ...]

As the Baz Instance to be created shall belong to one of foo's Bar instances, I'd like to limit the choices for that field to the Bar instances belonging to foo.

So far, I've found ForeignKey.limit_choices_to which seems to be for use in the Model and This question which is 9 years old and thus probably has an outdated answer. If it isn't outdated I'd like some advice on how to access the form object mentioned in the accepted answer and how to pass the Bar id to the CreateView.

jhhl
  • 101
  • 7
  • This question should get you started: https://stackoverflow.com/questions/5806224/sending-request-user-object-to-modelform-from-class-based-generic-view-in-django – Alasdair Nov 08 '17 at 14:58

1 Answers1

6

After looking at the question @Alasdair pointed me to (thanks for the hint), I came up with this:

# forms.py
class BazForm(forms.ModelForm):
    model = Baz
    fields = ['bar', ...]

    def __init__(self, *args, **kwargs):
        foo_id = kwargs.pop('foo_id')
        super(BazForm, self).__init__(*args, **kwargs)
        self.fields['bar'].queryset = Bar.objects.filter(foo_id=foo_id)

and

# views.py
class BazCreateView(CreateView):
    form_class = BazForm
    model = Baz

    def get_form_kwargs(self):
        kwargs = super(BazCreateView, self).get_form_kwargs()
        kwargs.update({'foo_id': self.kwargs.get('foo_id')})
        return kwargs

That seems to work. If I'm doing something wrong here, please comment.

Jimmar
  • 4,194
  • 2
  • 28
  • 43
jhhl
  • 101
  • 7