Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple field foreign key in django

I have two models in django with definitions below. CreativeStatus model :

class RtbdCreativeStatus(models.Model):
    creative_id = models.CharField(max_length=500, primary_key=True)
    advertiser_id = models.CharField(max_length=100, primary_key=True)
    exposure_level = models.CharField(max_length=125)
    modified_on = models.DateTimeField()
    modified_by = models.CharField(max_length=100)


class RtbdCreative(models.Model):
    id = models.AutoField(primary_key=True)
    advertiser_id = models.ForeignKey(RtbdCreativeStatus, on_delete=models.CASCADE)
    creative_id = models.ForeignKey(RtbdCreativeStatus, on_delete=models.CASCADE)
    country_id = models.IntegerField()
    adm = models.CharField(max_length=255, null=True, blank=True)
    sample_url = models.CharField(max_length=500)
    landing_page = models.CharField(max_length=500, null=True, blank=True)
    html = models.CharField(max_length=500)
    creative_attributes = models.CommaSeparatedIntegerField(max_length=150, null=True, blank=True)
    advertiser_domains = models.CharField(max_length=500)
    description = models.CharField(max_length=500, null=True, blank=True)
    created_on = models.DateTimeField(auto_now=True, auto_now_add=True)
    creative_type = models.CharField(max_length=50, null=True, blank=True)
    demand_source_type_id = models.IntegerField()
    revalidate = models.BooleanField(default=False)

(creative_id, advertiser_id ) combination is unique in my CreativeStatus table . I want that combination to be my foreign key for Creative table. I tried adding it but i get this error .Screenshot of the error in django

1)How do i achieve this join with two key combination as my foreign key .

2)What should be my query to fetch all the creatives with their status from CreativeStatus table .

UPDATE 1

on reading the answers below , i updated my model as mentioned below :

class RtbdCreative(models.Model):
    id = models.AutoField(primary_key=True)
    advertiser_id = models.ForeignKey(RtbdCreativeStatus, to_field='advertiser_id', related_name='advertiser', db_column='advertiser_id', on_delete=models.CASCADE)
    creative_id = models.ForeignKey(RtbdCreativeStatus, to_field='creative_id', related_name='creative', db_column='creative_id', on_delete=models.CASCADE)
    country_id = models.IntegerField()
    adm = models.CharField(max_length=255, null=True, blank=True)
    sample_url = models.CharField(max_length=500)
    landing_page = models.CharField(max_length=500, null=True, blank=True)
    html = models.CharField(max_length=500)
    creative_attributes = models.CommaSeparatedIntegerField(max_length=150, null=True, blank=True)
    advertiser_domains = models.CharField(max_length=500)
    description = models.CharField(max_length=500, null=True, blank=True)
    created_on = models.DateTimeField(auto_now=True, auto_now_add=True)
    creative_type = models.CharField(max_length=50, null=True, blank=True)
    demand_source_type_id = models.IntegerField()
    revalidate = models.BooleanField(default=False)

Now i am getting this errorenter image description here . I have combination of advertiser_id , craetive_id as unique . But django expects both to be unique. What can i do to make it work ?

like image 913
Sourav Prem Avatar asked Oct 18 '22 09:10

Sourav Prem


2 Answers

As mentioned in ERRROS, you need to add related_name as argument, when you want to add more than one foreign key for same Model.

class Creative(models.Model):
    id = models.AutoField(primary_key=True)
    advertiser_id = models.ForeignKey(RtbdCreativeStatus,
                                      related_name="Advertiser", on_delete=models.CASCADE)
    creative_id = models.ForeignKey(RtbdCreativeStatus,
                                    related_name="Creative",
                                    on_delete=models.CASCADE)
    country_id = models.IntegerField()
    adm = models.CharField(max_length=255, null=True, blank=True)
    sample_url = models.CharField(max_length=500)
    landing_page = models.CharField(max_length=500, null=True, blank=True)
    html = models.CharField(max_length=500)
    creative_attributes = models.CommaSeparatedIntegerField(
        max_length=150, null=True, blank=True)
    advertiser_domains = models.CharField(max_length=500)
    description = models.CharField(max_length=500, null=True, blank=True)
    created_on = models.DateTimeField(auto_now=True, auto_now_add=True)
    creative_type = models.CharField(max_length=50, null=True, blank=True)
    demand_source_type_id = models.IntegerField()
    revalidate = models.BooleanField(default=False)
like image 91
Vaibhav Mule Avatar answered Oct 22 '22 10:10

Vaibhav Mule


I just saw a parameter as to_fields for models.ForeignObject, superclass of models.ForeignKey. It might be used in this case for defining foreign key for composite primary key or unique keys.

    advertiser_creative_id = models.ForeignObject(RtbdCreativeStatus, to_fields=['advertiser_id', 'creative_id'], related_name='abc', on_delete=models.CASCADE)

There is a from_fields parameter as well. It can be used to map the fields with to_fields. Refer https://docs.djangoproject.com/en/2.2/_modules/django/db/models/fields/related/

like image 24
S.K Avatar answered Oct 22 '22 10:10

S.K