art_cs
art_cs

Reputation: 791

Using different fields in foreignkey django

I have to use different fields as ForeignKey, not only str method field !?

I tried this but it seems that doesn't work and it only return str method fields data:

class ModelA(models.Model):
    admin = models.ForeignKey(User,on_delete=models.CASCADE)
    product = models.ForeignKey(Product,on_delete=models.CASCADE)
    invoice_id = models.IntegerField(unique=True)

    def __str__(self):
        return self.product.name

class ModelB(models.Model):
    admin = models.ForeignKey(User,on_delete=models.CASCADE)
    invoice = models.ForeignKey(ModelA,to_field='invoice_id',on_delete=models.CASCADE)

I need to show, in ModelB invoice field, all invoice_ids, but it displays products ? Thanks for helping

Upvotes: 1

Views: 58

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476584

I have to use different fields for as ForeignKey not only str method field!?

A ForeignKey never uses the str method. It stores by default the primary key of the object it refers to. If you specify a to_field=… [Django-doc], then it will store that field.

However if you have a ModelB object mymodelb, and you access the ForeignKey, so mymodelb.invoice, it will lazily fetch the related object. It will thus in this case make a query that looks like SELECT modela.* FROM modela WHERE invoice_id = ….

If you wan the value that the ForeignKey stores, you can make use of fieldname_id, so in this case .invoice_id. This thus means that you can access the invoice id with:

mymodelb.invoice_id  # invoice_id of the referred ModelA object

If you want to show invoice_ids in a Form, you should override the ModelChoiceField [Django-doc], then in the ModelBForm you can use this subclass:

from django import forms

class InvoiceChoiceField(ModelChoiceField):
    
    def label_from_instance(self, obj):
        return str(obj.invoice_id)

class ModelBForm(forms.ModelForm):
    invoice = InvoiceChoiceField(queryset=ModelA.objects.all())

But in that case, you do not need to specify a to_field at all in the ForeignKey.Models deal with how data is stored, not with how data is rendered.

Upvotes: 2

Related Questions