1👍
- The issue with using
limit_choices_to
is that it attempts to filter choices based on the customer_id attribute of the related model (Address).
However, it isn’t aware of the specific customer instance for which this ForeignKey field is being used. Consequently, it doesn’t have access to the customer instance being created, making it impossible to dynamically filter choices based on the specific customer instance’s attributes.
You can use limit_choices_to to limit choices based on static criteria, such as the type (e.g., limiting choices to addresses with the type "home").
- If you know you’ll only ever need two addresses for each customer and won’t require customization later, you can link Address to Customer like this:
class Customer(models.Model):
# Fields for Customer model...
billing_address = models.ForeignKey("Address", on_delete=models.CASCADE, null=True)
shipping_address = models.ForeignKey("Address", on_delete=models.CASCADE, null=True)
With this setup, you can assign an Address object to a Customer when defining the Customer or later on. You can even use one address for both billing and shipping:
billing_address = Address(street=..., ...)
new_customer = Customer(..., billing_address=billing_address, shipping_address=billing_address)
Or you can assign addresses when declaring the Customer:
Customer(..., billing_address=Address(street=..., ...), shipping_address=Address(street=..., ...))
Find addresses not linked to any customer
unlinked_addresses = Address.objects.filter(customer__isnull=True)
Get all addresses for the customer
address = customer.address_set.filter()
or access directly
customer.shipping_address
customer.billing_address
- However, if you need to allow customers to define multiple addresses, it’s advisable to link Customer to Address as follows:
class AddressType(models.IntegerChoices):
BILLING = 1, _("Billing address")
SHIPPING = 2, _("Shipping address")
class Customer(models.Model):
# Fields for Customer model...
class Address(models.Model):
# Fields for Address model...
address_type = models.PositiveSmallIntegerField(choices=AddressType.choices)
customer = models.ForeignKey("Customer", on_delete=models.CASCADE, null=True)
class Meta:
constraints = [
UniqueConstraint(
name="unique_address_type",
fields=["customer", "address_type"],
)
]
Side note: Be cautious about using the keyword "zip" since it’s reserved for Python syntax.
0👍
My immediate thought is that two customers might share an address (housemates? people in a business?) as well as one customer having multiple addresses. So it’s not a ForeignKey
relationship, but a ManyToMany
relationship.
There’s quite a steep learning curve associated with these, but it has to be climbed because that’s what the data says! And it provides a large part of the solution at the forms level (also Django admin), because every address will have a customer_set
, and every customer will have an address_set
.
- [Answered ]-How to use vagrant to develop on django locally and then deploy to EC2/Azure?
- [Answered ]-Setting the right URL to make bool false Django
- [Answered ]-Set creator automatically with DjangoRestFramework