django - Django:两个模型之间的两种关系
问题描述
我正在努力创建两个具有两种关系的模型。
我的目标是一个人可以拥有多个对象,并且始终拥有一个最喜欢的对象(他们拥有)。
因此,准确地说,约束可以总结如下:
- 1:n 关系人 - 对象(一个人[独家]拥有多个对象)
- n:1 关系人 - 对象(最喜欢的对象,每个人都有一个最喜欢的对象)
- person.(favorite object).owner = person(一个人必须拥有他们最喜欢的对象,这使得最喜欢的对象的 n:1 关系更像是“从对象的角度来看可选的 1:1”)
class Person(models.Model):
favorite_object = models.ForeignKey('Object')
class Object(models.Model):
owner = models.ForeignKey(Person)
首先,我收到一个错误,指出我应该添加一个related_name
来帮助解决反向引用,我想知道这里最好的做法是什么,因为从对象的角度来看,最喜欢的关系是可选的。
我是否将所有者更改为
owner = models.ForeignKey(Person, related_name="+")
首先要避免反向引用?但是,如何查询所有者的所有对象?我什至可以强制要求最喜欢的对象必须由 Django 模型拥有吗?
其次,我首先如何创建对象?他们相互依赖。
如果没有最喜欢的对象,我无法创建用户,也无法在不知道其所有者的情况下创建对象。请注意,在我的情况下,这是一个必要的约束。
我会做这样的事情,但它似乎不起作用
with transaction.atomic():
my_person = Person()
my_object = Object(owner=my_person)
my_person.favorite_object = my_object
my_person.save()
my_object.save()
例如,我可以允许Object.owner
为 NULL,但这会放松我对每个对象都需要拥有所有者的一般约束。
编辑:
它似乎
favorite_object = models.ForeignKey('Object', related_name="+")
而不是排除反向关系可能是一个好主意,因为从对象引用回所有者似乎没有必要。首先,无论如何我都可以通过所有者属性检查所有者(我的约束是喜欢一个对象的人也是他们的所有者)。其次,这种反向关系并不总是存在。
解决方案
也许您可以在数据库中有一个“虚拟”对象,这样 Person() 对象就有一个 favorite_object 并且不会创建失败,然后在您创建人的同一视图中,使用该人创建一个对象(这将是人们最喜欢的对象)并更新 Person() 以使用您刚刚创建的对象而不是虚拟对象。
我认为它看起来像这样:
@api_view(['POST'])
@permission_classes((AllowAny,))
def api_user_registration_view(request):
if request.method == 'POST':
dummy_object = Object.objects.get(name='dummy')
person_serializer = PersonRegistrationSerializer(favorite_object=dummy_object, data=request.data)
data = {
}
if person_serializer.is_valid():
person = person_serializer.save()
object_serializer = ObjectRegistrationSerializer(owner=person)
if object_serializer.is_valid():
object_serializer.save()
else:
data = serializer.errors
else:
data = serializer.errors
return Response(data)
在 serializers.py 中,您只需为每个模型声明注册序列化程序
class PersonRegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = '__all__'
class ObjectRegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = Object
fields = '__all__'
我希望这有助于或至少为您指明正确的方向。
推荐阅读
- spring - 关于 spring Oauth 2 的正确指南
- cordova - 在我的应用程序中应用了科尔多瓦通用链接插件,但是当我在浏览器上打开网站时,应用程序无法自动打开
- javascript - 时刻js中带有日期数字的工作日
- ios - com.google.GTLRErrorObjectDomain 代码=503 在 Firebase 登录目标 C
- scala - 使用 Spark Dataframe 遍历记录并根据某些条件将当前值与先前值连接起来
- sharepoint - 对动态创建的 Sharepoint 文档库使用客户端渲染(js 链接)
- node.js - 如何在带有节点 js 的 Twilio 可编程视频中使用用户自定义名称
- php - PHP 和 HTML 中的相关下拉列表
- php - 如何在functions.php中设置类的样式
- html - 在 Angular 6 模板中解析 Json 数据