# Queryset a foreign key field in inlineformset

**URL:** <https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766>\
**Category:** Using Django\
**Created:** [January 24, 2022, 6:24pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766 "2022-01-24T18:24:12Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![seb\_lefloch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/seb_lefloch/32/7189_2.png) [@seb\_lefloch](https://forum.djangoproject.com/u/seb_lefloch)\
**Post date:** [January 24, 2022, 6:24pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/1 "2022-01-24T18:24:12Z")

</div>

Hello,  
I created a inlineformset form with cbv. It works fine but I have a problem with a field which is a foreign key (link with an another model than the two models in the inlineformset).  
I want to limit the choice of this field. I must be related to the id of the parent.  
Example : I have a contract with supplier’s contacts. With the inlineformset, I can select the contacts and affect a role. How can I limit the dropdown with only the contacts of the supplier ?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 24, 2022, 8:04pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/2 "2022-01-24T20:04:16Z")

</div>

It would be easiest to discuss something like this in the context of the actual models, forms, and view involved. If you post your code, you’re more likely to get a more useful response.

(When posting code here, enclose each file between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted, which is critical with Python.)

---

<div class="post-metadata">

**Author:** ![seb\_lefloch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/seb_lefloch/32/7189_2.png) [@seb\_lefloch](https://forum.djangoproject.com/u/seb_lefloch)\
**Post date:** [January 25, 2022, 8:10am UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/3 "2022-01-25T08:10:00Z")

</div>

Thank you Ken. I really hope you can help me. 🙂 This is my code :

Models :

```auto
class Contrat(models.Model):
    code_frn = models.ForeignKey(Fournisseur, related_name='contrat_fournisseur', on_delete=models.CASCADE)
    annee_effective = models.IntegerField(blank=False, default='2022')
    statut_choice = (
        ('Négociation', 'Négociation'),
        ('Finalisé', 'Finalisé'),
        ('Envoyé', 'Envoyé'),
        ('Signé', 'Signé'),
        ('Annulé', 'Annulé'),
    )
    statut_contrat = models.CharField(max_length=30, default='11', blank=False, null=False, choices=statut_choice)
    code_perimetre = models.ForeignKey(Perimetre, related_name='contrat_perimetre', on_delete=models.CASCADE)
    date_envoi = models.DateField(blank=True, null=True)
    date_signature = models.DateField(blank=True, null=True)

    def get_absolute_url(self):
        return reverse('contrat_detail', kwargs={'pk': self.pk})

    def __str__ (self):
        return str(self.code_frn)

class Fournisseur(models.Model):
    code_frn = models.CharField(max_length=5, null=False, unique=True)
    libellé_frn = models.CharField(max_length=150)
    forme_juridique = models.CharField(max_length=50, blank=True)
    capital = models.CharField(max_length=20, blank=True)
    rcs = models.CharField(max_length=150, blank=True)
    adresse1 = models.CharField(max_length=100)
    adresse2 = models.CharField(max_length=100, blank=True)
    cp = models.CharField(max_length=10, blank=True)
    ville = models.CharField(max_length=100)
    pays = models.CharField(max_length=50)
    num_tva = models.CharField(max_length=50, blank=True)
    statut_choice = (
        ('Actif', 'Actif'),
        ('Inactif', 'Inactif')
    )
    statut = models.CharField(max_length=30, blank=True, null=True, choices=statut_choice)
    categorie = models.ForeignKey(Categorie, related_name='categorie_fournisseur', on_delete=models.CASCADE)

    def __str__ (self):
        return self.libellé_frn

class Contact(models.Model):
    code_frn = models.ForeignKey(Fournisseur, related_name='contact_fournisseur', on_delete=models.CASCADE)
    civilite_choice = (('M.', 'M.'), ('Mme', 'Mme'))
    civilite = models.CharField(max_length=3, blank=False, null=False, choices=civilite_choice)
    nom = models.CharField(max_length=30, blank=False, null=False)
    prenom = models.CharField(max_length=30, blank=False, null=False)
    qualite = models.CharField(max_length=70, blank=False, null=False)
    telephone = models.CharField(max_length=30, blank=True, null=True)
    email = models.CharField(max_length=150, blank=False, null=False)
    statut_choice = (
        ('Actif', 'Actif'),
        ('Inactif', 'Inactif')
    )
    statut = models.CharField(max_length=30, default='Actif', blank=False, null=False, choices=statut_choice)

    def __str__ (self):
        return str(self.nom)

class Contact_role_contrat(models.Model):
    code_contrat = models.ForeignKey(Contrat, related_name='code_contrat_contact', on_delete=models.CASCADE)
    code_contact = models.ForeignKey(Contact, related_name='code_fournisseur_contact', on_delete=models.CASCADE)
    code_role_choice = (('11', 'Signataire'), ('12', 'Commercial'), ('13', 'Dirigeant'), ('14', 'Comptable'))
    code_role = models.CharField(max_length=30, default='11', blank=True, null=True, choices=code_role_choice)

    def __str__ (self):
        return str(self.code_contact)

```

Views :

```auto
class ContratsContactRoleEditView(SingleObjectMixin, FormView):
        model = Contrat
        template_name = 'contrat/contrat_contact_edit.html'

        def get(self, request, *args, **kwargs):
            self.object = self.get_object(queryset=Contrat.objects.all())
            return super().get(request, *args, **kwargs)

        def post(self, request, *args, **kwargs):
            self.object = self.get_object(queryset=Contrat.objects.all())
            return super().post(request, *args, **kwargs)

        def get_form(self, form_class=None):
            return ContratContactFormset(**self.get_form_kwargs(), instance=self.object)

        def form_valid(self, form):
            form.save()
            messages.add_message(
                self.request,
                messages.SUCCESS,
                'Modifications enregistrées.'
            )
            return HttpResponseRedirect(self.get_success_url())

        def get_success_url(self):
            return reverse('contrat_detail', kwargs={'pk': self.object.pk})

```

Forms :

```auto
class ContratContactForm(forms.ModelForm):

    def __init__ (self, *args, **kwargs):
        super(ContratContactForm, self). __init__ (*args, **kwargs)
        #There is the problem : I don't how to find the code_frn value ? How can I have the code of the supplier to filter the field code_contact ?
        code_frn = Fournisseur.objects.get(id=1)
        self.fields['code_contact'].queryset = \
             Contact.objects.filter(code_frn_id=code_frn)

ContratContactFormset = inlineformset_factory(Contrat, Contact_role_contrat, fields=('code_contrat', 'code_contact', 'code_role',)
                                              , extra=1, form=ContratContactForm)

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 25, 2022, 12:43pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/4 "2022-01-25T12:43:09Z")

</div>

Thank you for posting this.

> [@seb\_lefloch](#):
>
> With the inlineformset, I can select the contacts and affect a role. How can I limit the dropdown with only the contacts of the supplier ?

To make sure I’m clear -

- Your inline formset is a set of `ContratContactForm` instances
- `ContratContactForm` is using all fields in `Contact_role_contrat` in the form.
- For _each_ form, you want to limit the drop-down widget of the `code_contact` field.

Questions:  
Is this all going to be the same set in the drop-downs for `code_contact`? Or are you looking to get a different set for each instance of the form?

What is the specific condition or restriction to apply to the drop-down?

How does this relate to the `extra` form? Should it be constrained?

(The solution is going to be slightly different depending on your answers.)

---

<div class="post-metadata">

**Author:** ![seb\_lefloch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/seb_lefloch/32/7189_2.png) [@seb\_lefloch](https://forum.djangoproject.com/u/seb_lefloch)\
**Post date:** [January 25, 2022, 1:23pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/5 "2022-01-25T13:23:21Z")

</div>

I have a contract (contrat) with a supplier (fournisseur) and I have the supplier’s contact (contact). I want to select the good contact (the contact belongs to the supplier and I affect a role on this contract, like signatory for example)

With the drop down, I want to constrain the user to be able to select only the contacts of the supplier consulted.  
The drop-down for code\_contact must contain all the contacts for the code\_frn (this instance).

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 25, 2022, 2:41pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/6 "2022-01-25T14:41:08Z")

</div>

Unfortunately, I’m _still_ not sure I’m following you here.

- The Contrat being used has a foreign key to Fournisseur.
- The Contact\_role\_contrat has foreign keys to both Contrat (which is given because _this_ Contract\_role\_contrat is being rendered _because_ it’s related to some identified Contrat) and to Contact (field name: code\_contact).
- Contact _also_ has a foreign key to Fournisseur.

So, if I’m correct, you want the `code_contact` field to list _all_ Contact relating to the same Fournisseur as the Contrat referenced by the Contact\_role\_contrat being edited.

Assuming `this_contact_role_contrat` is the name of the “current” `Contact_role_contrat` for which the form is being generated, then the set of Contact desired would be described as:  
`Contact.objects.filter(fournisseur __contrat__ code_contrat_contact=this_contact_role_contrat)`  
(Alternately: `Contact.objects.filter(fournisseur__contrat=this_contact_role_contrat.code_contrat)`)  
(You can test these in the shell to verify you get the proper results.)

Have I finally got it?

---

<div class="post-metadata">

**Author:** ![seb\_lefloch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/seb_lefloch/32/7189_2.png) [@seb\_lefloch](https://forum.djangoproject.com/u/seb_lefloch)\
**Post date:** [January 25, 2022, 3:18pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/7 "2022-01-25T15:18:14Z")

</div>

Yes, you understand what I want.  
I try your 2 solutions but I have an error : name ‘this\_contact\_role\_contrat’ is not defined.  
Did I miss something ?

class ContratContactForm(forms.ModelForm):

```
def __init__ (self, *args, **kwargs):
    super(ContratContactForm, self). __init__ (*args, **kwargs)
    self.fields['code_contact'].queryset = \
        Contact.objects.filter(fournisseur __contrat__ code_contrat_contact=this_contact_role_contrat)
```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 25, 2022, 3:23pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/8 "2022-01-25T15:23:19Z")

</div>

> [@seb\_lefloch](#):
>
> I try your 2 solutions but I have an error : name ‘this\_contact\_role\_contrat’ is not defined.

> [@KenWhitesell](#):
>
> Assuming `this_contact_role_contrat` is the name of the “current” `Contact_role_contrat` for which the form is being generated

You need to select a Contact\_role\_contrat object, and assign it to `this_contact_role_contrat`.

---

<div class="post-metadata">

**Author:** ![seb\_lefloch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/seb_lefloch/32/7189_2.png) [@seb\_lefloch](https://forum.djangoproject.com/u/seb_lefloch)\
**Post date:** [January 26, 2022, 2:53pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/9 "2022-01-26T14:53:14Z")

</div>

Thank you, It works when I have already a contact selected in my contract. But when I have none contact entered in the InlineFormSet, I can’t retrieve the id of the contract because the instance is none.  
How can I retrieve the id of the contract ? The id is in the current url…  
For example, I write manually 29 for the pk.

‘’’  
class ContratContactForm(forms.ModelForm):

```
def __init__ (self, *args, **kwargs):
    super(ContratContactForm, self). __init__ (*args, **kwargs)
    if self.instance.code_contrat_id:
        code_frn = Contrat.objects.get(id=self.instance.code_contrat_id)
        self.fields['code_contact'].queryset = \
              Contact.objects.filter(code_frn__libellé_frn=code_frn)
    else:
        code_frn = get_object_or_404(Contrat, pk=29)
        self.fields['code_contact'].queryset = \
            Contact.objects.filter(code_frn__libellé_frn=code_frn)

```

‘’’

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 26, 2022, 3:20pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/10 "2022-01-26T15:20:00Z")

</div>

Your CBV stores the url args in `self.kwargs` You can then pass that value in to the initializer for your form when you create the instance of your formset.

See the text and examples at [Built-in class-based generic views | Django documentation | Django](https://docs.djangoproject.com/en/4.0/topics/class-based-views/generic-display/#dynamic-filtering)

---

<div class="post-metadata">

**Author:** ![seb\_lefloch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/seb_lefloch/32/7189_2.png) [@seb\_lefloch](https://forum.djangoproject.com/u/seb_lefloch)\
**Post date:** [January 28, 2022, 8:55am UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/11 "2022-01-28T08:55:44Z")

</div>

Thank you for the link. I’m trying to understand how it works but I still have a bug.

In my CBV, I add this :

```auto
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            code_frn = Contrat.objects.get(id=self.kwargs['pk'])
            context['code_contact'] = Contact.objects.filter(code_frn__libellé_frn=code_frn)

            return context

```

When I use print(context), I can see the contact of my supplier (fournisseur) even if I have none contact. → Good news.  
But now, how I can use this for filtering my dropdown code\_contact ?  
I tried def QuerySet(self)… but it doesn’t work. I just want to filter my foreign key with the context…  
Please help me…  
Thank you.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 28, 2022, 5:38pm UTC](https://forum.djangoproject.com/t/queryset-a-foreign-key-field-in-inlineformset/11766/12 "2022-01-28T17:38:22Z")

</div>

See [Passing custom parameters to formset forms](https://docs.djangoproject.com/en/4.0/topics/forms/formsets/#passing-custom-parameters-to-formset-forms). Your _view_ will need to pass that id when you create the forms using `ContratContactFormset`. Your ` __init__ ` method of the form will then have that parameter passed through to it.
