我在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表中是唯一的。我希望这个组合成为Creative表的外键。我尝试添加它但我收到此错误。
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)
现在我收到此错误。我将advertiser_id,craetive_id组合为唯一。但是django希望两者都是独一无二的。我能做些什么让它发挥作用?
答案 0 :(得分:1)
如ERRROS中所述,当您要为同一个Model添加多个外键时,需要添加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)
答案 1 :(得分:0)
当您向同一个表添加多个ForeignKeys时,您应该覆盖字段的related_name
选项,以便可以轻松区分字段。
您可以实施自定义验证,以检查creative_id
和advertiser_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
查询您的广告素材。
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()
答案 2 :(得分:0)
我刚刚看到 models.ForeignObject ( models.ForeignKey 的超类)的参数为to_fields
。在这种情况下,可以使用它为复合主键或唯一键定义外键。
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/