Home > Enterprise >  How to annotate integer as a ForeignKey in django?
How to annotate integer as a ForeignKey in django?

Time:09-13

I have this model:

class Order(Model):
    sale_address = ForeignKey(Address)
    purchase_address = ForeignKey(Address)

and want to conditionally annotate one address or another depending on some condition, as a ForeignKey:

order = Order.objects.annotate(
    address=...  # sale_address if current user is seller
).first()

assert isinstance(order.address, Address)  # True

How can I do that?

I've tried this:

annotate(
    address_id=Case(
        When(
            user_role='SELLER',
            then=F('sale_address'),
        ),
        When(
            user_role='BUYER',
            then=F('purchase_address'),
        ),
    ),
)

but in this case address_id is just an integer and I get N 1 issues when making list of orders with address.region.

CodePudding user response:

As @AKX says, it is likely better to just .select_related(…) [Django-doc] the two Addresses, and then use a @property to determine which one to use, so:

class Order(models.Model):
    user_role = …
    sale_address = models.ForeignKey(
        Address, on_delete=models.CASCADE, related_name='sale_orders'
    )
    purchase_address = models.ForeignKey(
        Address, on_delete=models.CASCADE, related_name='purchase_orders'
    )

    @property
    def address(self):
        if self.user_role == 'SELLER':
            return self.sale_address
        if self.user_role == 'BUYER':
            return self.purchase_address
  • Related