I'm working on a Django project where I have several customers, each of which can have multiple postal addresses (office 1, office 2, office 3, ...). I have to choose the default address for each customer.
I created a model for postal addresses with ForeignKey pointing to the customer model and in my customer model I entered a PositiveIntegerField to contain the default postal address ID. The problem is that I do not know how to filter in the Admin Form only the addresses relevant to the client and show the description of the address instead of a PositiveIntegerField.
Some advice?
答案 0 :(得分:1)
I created a model for postal addresses with
ForeignKey
pointing to the customer model and in my customer model I entered aPositiveIntegerField
to contain the default postal address ID.
Don't do that. This is in fact a relation, so you should use the tool that is constructed for this: a ForeignKey
[Django-doc].
We can thus construct something like:
class Customer(models.Model):
default_address = models.ForeignKey(
'app.Address',
on_delete=models.SET_NULL,
null=True
)
class Address(models.Model):
customer = models.ForeignKey(
Customer,
on_delete=models.CASCADE,
related_name='addresses'
)
In a ModelForm
you can then restrict the options to addresses that belong to that specific instance. For example:
class CustomerModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CustomerModelForm, self).__init__(*args, **kwargs)
if self.instance:
self.fields['default_address'].queryset = Address.objects.filter(
customer=self.instance
)
class Meta:
model = Customer
So here we limit the options to addresses that belong to the customer.
The advantage of using a ForeignKey
is that the database will protect referential integrity (the id can not refer to a non-existing address), and furthermore all advanced querying you can do with Django's ORM is still possible here. You can thus filter on Customer
s with a default_address
that is located in London for example with something like Customer.objects.filter(default_address__city='London')
(given an address has a city
field).