簡體   English   中英

Django 中的多字段外鍵

[英]Multiple field foreign key in django

我在 Django 中有兩個模型,定義如下。 創意狀態模型:

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,adverter_id) 組合在我的 CreativeStatus 表中是唯一的。 我希望該組合成為我的 Creative 表的外鍵。 我嘗試添加它,但出現此錯誤。 django 中的錯誤截圖

1)我如何使用兩個組合鍵作為我的外鍵來實現這種連接。

2)從 CreativeStatus 表中獲取所有廣告及其狀態的查詢應該是什么。

更新 1

在閱讀下面的答案時,我更新了我的模型,如下所述:

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)

現在我收到這個錯誤在此處輸入圖片說明 . 我將 adser_id 、 craetive_id 組合為 unique 。 但是 django 期望兩者都是獨一無二的。 我該怎么做才能讓它發揮作用?

我剛才看到一個參數作為to_fieldsmodels.ForeignObject,models.ForeignKey的超類。 在這種情況下,它可能用於為復合主鍵或唯一鍵定義外鍵。

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

還有一個from_fields參數。 它可用於使用to_fields映射字段。 參考https://docs.djangoproject.com/en/2.2/_modules/django/db/models/fields/related/

如 ERRROS 中所述,當您想為同一模型添加多個外鍵時,您需要添加 related_name 作為參數。

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)

當您向同一個表添加多個外鍵時,您應該覆蓋字段的related_name選項,以便可以輕松區分字段。

您可以實施自定義驗證來檢查creative_idadvertiser_id唯一性,

class Creative(models.Model):
    advertiser_id = models.ForeignKey(CreativeStatus,
                                  related_name="advertisers")
    creative_id = models.ForeignKey(CreativeStatus,
                                related_name="creatives")

    def clean(self):
        data = self.cleaned_data
        if not data['advertiser_id'] == data['creative_id']:
            raise ValidationError("Unique Constraint failed {}, {}".format(self.advertiser_id, self.creative_id))
        return data

您可以使用相關名稱從CreativeStatus查詢您的廣告CreativeStatus

creative_status_obj = CreativeStatus.objects.get(pk=some_pk)#or any query.
#All creatives of the given object can be queried using reverse relation.
creatives = creative_status_obj.creatives.all()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM