【问题标题】:Generic relationship many to one or many to many?多对一或多对多的通用关系?
【发布时间】:2018-10-03 11:13:12
【问题描述】:

我面临以下问题:

我想创建一个可以关联到不同模型 (Generic Relationship Django) 并包含以下信息的结果模型(又名:Pros and Conts 模型):

Consequences : Boolean (Positive or Negative)
Of : Model_Primary_Key
Reason : Text
Author : User_Primary_Key
Users_likes : List<Users>

一个对象(属性)可以有很多结果,但一个结果只属于一个结果,所以它应该是多对一的关系。

问题是我不知道后果模型和其他模型之间的关系是多对一还是多对多。

通常当你有一对多时,拥有多个的部分包含另一个的外键,但如果我这样做,外键将是 AuthorOf 并且该集合将是复合主键,但如果我在这里这样做,用户不能对每个对象产生更多后果,而且应该是可能的。

所以我找到的唯一解决方案是在结果中添加一个 id 作为主键,所以最后它就像多对多关系一样工作,因为最后就像Associative entity 一样工作。

那么在我的实体关系图的最后,我应该如何表示这种关系?是一对多还是多对多?

【问题讨论】:

  • 当您提到“用户不能对每个对象产生超过后果”时,您的意思是每个用户只能有一个后果,还是您指的是对象模型?请澄清。
  • @user7485741 我的意思是用户应该能够为每个对象创建多个结果,如果我不为结果创建 PK,我遇到的问题是复合主键将是 Author_ID和 Object_ID 并且用户将无法创建多个结果,因为复合 PK 将被重复,我希望我能回答你

标签: django database-design django-models relational-database


【解决方案1】:

您可以使用 djangos 隐式 AutoField 作为主键,NOT 添加 unique_together 约束来克服您描述的障碍。

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class Consequence(models.Model):
    # implicit AutoField
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    author = models.ForeignKey(User)
    is_positive_consequence = models.BooleanField()
    reason = models.CharField(max_length=200)

class ConsequenceLike(models.Model):
    # implicit AutoField
    parent = models.ForeignKey(Consequence)
    user = models.ForeignKey(User)

这样一个User 可以创建许多指向同一个对象的Consequence 实例,因为没有唯一约束。

这为您以后过滤提供了很大的灵活性:

# created by this user
user_instance.consequence_set.all()

# created by this user, filtered by content type
from myapp.models import MyCarModel
user_instance.consequence_set.filter(
    content_type=ContentType.objects.get_for_model(MyCarModel))

# created by this user, filtered by object instance
my_car = MyCarModel.objects.first()
user_instance.consequence_set.filter(
    content_type=ContentType.objects.get_for_model(my_car.model),
    object_id=my_car.pk)

【讨论】:

  • 只是一个想法(也许对我自己而言):如果ConsequenceLike 不会存储额外的数据,它可以被Consequence 模型上的ManyToManyField 替换。
  • 问题中给出的示例和这个答案对我来说似乎不完整,因为这里没有理由使用通用关系。同意上面的评论。
猜你喜欢
  • 2018-06-15
  • 2021-04-01
  • 1970-01-01
  • 2010-10-30
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多