Django field with foreignKey

20 Views Asked by At

I'm using Django v4.1 and have a foreignKey relationship I want to pull into a form.

The two models:

class Service(models.Model):
   client = models.ForeignKey("Client", on_delete=models.SET_NULL, null=True)
   # some other fields

and

class Client(models.Model):
    name = models.CharField(max_length=50)
    # a few more fields

The form:

class ServiceForm(forms.ModelForm):
    class Meta:
        model = Service
        fields = "__all__"

However, in the front-facing form, "Client" is generated, but without a SELECT field.

There is another model with a foreignKey relationship to Client, order:

class Order(models.Model):
    client = models.ForeignKey("Client", on_delete=models.SET_NULL, null=True)
    # more fields...

And it's form:

class OrderModelForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = "__all__"

Which renders as expected with a SELECT field for the Client.

Looking at the forms docs I experimented with (importing Client from models and) adding a ModelChoiceField, ("client": forms.ModelChoiceField(queryset=Client.objects.all()) both inside and outside of a widgets dict), but based on this SO post I'm thinking Django should be rendering that on it's own, as it is for Order.

Please share suggestions in debugging. Thanks much.

1

There are 1 best solutions below

0
MikeiLL On BEST ANSWER

Found it!

Even though I've been managing this project for a while, there are a lot of gaps in my Django knowledge. So I made a new Django app and app, adding a myapp/models.py with a minimized version of the problem app:

from django.db import models
from django.utils import timezone

class Client(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField(blank=True, null=True)

    def __str__(self):
        return self.name


class Order(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    client = models.ForeignKey("Client", on_delete=models.SET_NULL, null=True)


class Service(models.Model):
    client = models.ForeignKey("Client", on_delete=models.SET_NULL, null=True)
    name = models.CharField(max_length=50)

Sure enough, the SELECT fields were there for Client in both Service and Order views.

The barebones app doesn't even have a forms.py file in it, so I thought, what if I remove my ServiceForm(ModelForm) (from the real project) altogether?

But this raised an Exception because admin.py is importing ServiceForm from forms.

Hmmm. I hadn't thought to look in class ServiceAdmin.

Lo and behold:

readonly_fields = (
    "client",
    etc...
)

Removed that line and the SELECT field is there as expected.