djang中的多字段外键

2024-10-01 09:37:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个django模型,定义如下。 CreativeStatus模型:

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)组合在我的CreativeStatus表中是唯一的。我想把这个组合作为我创作表的外键。我试图添加它,但我得到了这个错误。Screenshot of the error in django

1)如何用两个键组合作为外键来实现这种连接。在

2)从CreativeStatus表获取所有creative及其状态的查询应该是什么。在

更新1

在阅读下面的答案后,我更新了我的模型,如下所述:

^{pr2}$

现在我得到了这个错误enter image description here。我有广告商的组合,克雷蒂夫的身份证是唯一的。但django希望两者都是独一无二的。我该怎么做才能让它成功呢?在


Tags: 模型idtrueonmodelsnulllengthmax
3条回答

如ERRROS中所述,当您要为同一个模型添加多个外键时,需要添加相关的\u 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)

当您向同一个表添加多个foreignkey时,您应该重写字段的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查询您的创意。在

^{pr2}$

我刚刚看到一个参数为to_fieldsfor模型.ForeignObject,超类模型.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/

相关问题 更多 >