DJango 和 Python 的外键设置问题
Posted
技术标签:
【中文标题】DJango 和 Python 的外键设置问题【英文标题】:Foreign key setup issue with DJango and Python 【发布时间】:2016-05-21 22:05:28 【问题描述】:我是 DJango 和 Python 的新手。现在我正在构建一个看起来像这样的模型:
属性 -> 房间 -> 图片。
我的意思是说用户可以拥有一个属性。 每个属性都可以有多个房间。 每个房间都可以有多个图像。现在我在 Room 模型中将属性 ID 设置为外键。
并且 Room ID 作为 Image 模型中的外键。
但是,当我在进行后期调用以插入特定房间和特定属性的新图像时。
即使属性 id 不存在,它也会创建一个图像对象。它只检查房间 ID。
虽然看跌期权执行得很好。
我想在插入新图片之前验证房间 ID 和属性 ID。
代码:
class PropertyRoom(models.Model):
pass
class PropertyRoom(models.Model):
property = models.ForeignKey(Property,related_name='rooms')
class PropertyRoomImage(AbstractImage):
room = models.ForeignKey(PropertyRoom, related_name='images')
【问题讨论】:
能否展示模型的相关部分? @Sayse 我已经添加了基本的模型结构。如果您需要更多说明,请告诉我。 你在属性房间的 fk 不能选择为空,因此每个房间必须有一个属性 是的,确实如此。但问题是,当我为特定房间添加图像时,它只检查房间 ID,我可以传递任何无效的属性 ID,但 post 调用仍然可以完美执行。 如果您可以包含相关代码会更容易。如果您将图像添加到特定房间,那么该房间已经具有特定属性 【参考方案1】:虽然理论上您的数据库应确保您拥有正确的数据,但在某些情况下可能并非如此,(IIRC 外键可能不会出现在 mysql 上的数据库中,使用混合表引擎(InnoDB 和 MyISAM))
假设您使用表单,您可以在上传表单中添加form validation。
def clean(self):
cleaned_data = super(MyForm, self).clean()
image = cleaned_data['image']
property = cleaned_data['property']
if image.room.property != property:
raise ValidationError("room property and supplied property don't match")
return cleaned_data
您也可以为模型编写相同的逻辑,但请注意默认情况下save
不会调用它们,因此您必须显式创建它们。 Official model validations documentation
image = PropertyRoomImage()
image.room = ...
image.full_clean() # call it explicitly as save doesn't
image.save()
【讨论】:
【参考方案2】:localhost:8000/api/properties/221/rooms/1/images 我正在发帖 例如,调用这个 url。房间 id 1 存在,但属性 id 221 存在 不是。
您需要自己实施此检查。模型不知道数据的所有层次结构;或您的业务规则。
您需要检查:
-
财产存在
被引用的房间是否属于该属性。
图像类型/尺寸正确;等
试试这样的模式:
from django.http import Http404
from django.shortcuts import get_object_or_404
def api(request, room=None, property=None):
property = get_object_or_404(Property, pk=property)
if not property.property_room_set.filter(pk=room).exists():
raise Http404
# other checks
# your normal logic
【讨论】:
【参考方案3】:localhost:8000/api/properties/221/rooms/1/images 例如,我正在对这个 url 进行 post call。房间 id 1 存在,但属性 id 221 不存在。
您根本不需要传递房间,或者如果您确实需要,那么您可以忽略它,您可以使用房间的 id 创建一个图像,如果您需要该属性,那么您可以通过room.property
访问正确的房间
【讨论】:
以上是关于DJango 和 Python 的外键设置问题的主要内容,如果未能解决你的问题,请参考以下文章