How to access ForeignKey properties from models.py in django

Question:

I want to access a property of another model from a model via ForeignKey. For example, if invoice_details is a ForeignKey to InvoiceMaster, then I want invoice_details to store the value of InvoiceMaster‘s invoice_number, instead of the primary key. How can I achieve this?

I have tried the following:

class OrderDetails(models.Model):
    purchase_order_number = models.IntegerField(blank=True, null=True)
    purchase_request_number = models.IntegerField(blank=True, null=True)
    delivery_no = models.IntegerField(blank=True, null=True)
    delivery_equipment = models.CharField(max_length=500, blank=True, null=True)
    delivery_quantity = models.IntegerField(blank=True, null=True)
    warranty_start_date = models.DateField()
    warranty_end_date = models.DateField()
    invoice_details = models.ForeignKey(InvoiceMaster, on_delete=models.CASCADE, blank=True, null=True).invoice_number
    vendor_id = models.ForeignKey(VendorDetails, on_delete=models.CASCADE, blank=True, null=True).vendor_id
    equipment_id = models.ForeignKey(EquipmentMaster, on_delete=models.CASCADE, blank=True, null=True).equipment_id
    is_visible = models.IntegerField(default=1)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    creation_date = models.DateTimeField(default=timezone.now)

Check invoice_details – I’ve tried adding .invoice_number at the end of the ForeignKey. Adding .invoice_details to InvoiceMaster within the ForeignKey parentheses gave me the following error: TypeError: ForeignKey(<django.db.models.query_utils.DeferredAttribute object at 0x10d632fd0>) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'

Here is the InvoiceMaster module:

class InvoiceMaster(models.Model):
    invoice_number = models.CharField(max_length=50, blank=True, null=True)
    equipment_name = models.ForeignKey(EquipmentMaster, on_delete=models.CASCADE, blank=True, null=True).name
    quantity = models.IntegerField(blank=True, null=True)
    is_visible = models.IntegerField(default=1)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    creation_date = models.DateTimeField(default=timezone.now)

For some reason, although I have done the same thing in equipment_name over here as I had in invoice_details, Django shows no error. For extra context, please take a look at EquipmentMaster, which equipment_name has a link to via ForeignKey.

class EquipmentMaster(models.Model):
    equipment_id = models.CharField(max_length=50, blank=True, null=True)
    equipment_type = models.CharField(max_length=50, choices=equipment_categories)
    name = models.CharField(max_length=200, blank=True, null=True)
    ram = models.CharField(max_length=100, blank=True, null=True)
    storage = models.CharField(max_length=100, blank=True, null=True)
    display_size = models.CharField(max_length=100, blank=True, null=True)
    paper_size = models.CharField(max_length=100, blank=True, null=True)
    operating_system = models.CharField(max_length=100, blank=True, null=True)
    is_visible = models.IntegerField(default=1)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    creation_date = models.DateTimeField(default=timezone.now)
Asked By: Robo

||

Answers:

May I ask what’s the purpose behind this?

A ForeignKey is only a relation to another field. If it is only because of displaying the invoice_number instead of the pk try adding the following:

class InvoiceMaster(models.Model):
    invoice_number = models.CharField(max_length=50, blank=True, null=True)
    # your other fields

    def __str__(self).
        return self.invoice_number

Otherwise you can only fetch invoice_number directly from the ForeignKey like

order = OrderDetails.objects.get(pk=1)
invoice_number = order.invoice_details.invoice_number
Answered By: hanspeters205

You can get details of the InvoiceMaster in OrderDetails by doing the following in OrderDetails:

@property
def invoice_number(self):
    return self.invoice_details.invoice_number

with this, you can get the invoice_number from order_details by calling order_details.invoice_number.

You might want to check if there is a relation before accessing the foreignkey field.

Answered By: Yousuf M.N
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.