Django 模型对此反向外键的最佳解决方案
Django models' best solution for this reverse ForeignKey
我正在做一个管理餐厅的个人项目。
我的两个模型面临问题,这些模型是 DiningRoom 和 Table.
DiningRoom 表示餐厅可能拥有的任何区域(例如,我们可以在建筑物内部有一个区域,而在建筑物的露台上有其他区域)。
在每个 DiningRoom 中,我们可以设置 Tables.
的布局
因此,我发现映射它的更面向对象的方法是通过多对一关系 (ForeignKey)。由于一个DiningRoom可以有多个Table,而一个Table只能在一个DiningRoom中。对吗?
所以我的模型是:
class DiningRoom(models.Model):
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=False)
name = models.CharField(max_length=50, null=False, blank=False)
rows = models.IntegerField(max=15, null=False)
cols = models.IntegerField(max=15, null=False) # rows and columns are for the room's grid layout.
class Table(models.Model):
row = models.IntegerField(max=15, null=False) # The row in the room's grid where the table is at.
col = models.IntegerField(max=15, null=False) # the column in the room's grid where the table is at.
dining_room = models.ForeignKey(DiningRoom, on_delete=models.CASCADE, null=False) # Here is the problem.
问题是,当我在视图中查询帐户的 DiningRoom 时,我还需要获取与查询集结果中每个 DiningRoom 相关的 Tables。
def dining_rooms(request):
try:
account = Account.objects.get(id=request.session['account_id'])
except Account.DoesNotExists:
return response(request, "error.html", {'error': 'Account.DoesNotExists'})
dining_rooms = DiningRoom.objects.filter(account=account)
但我还需要 dining_rooms!
中的 Table 个结果
我找到了两个可能的解决方案,但 none 对我来说似乎是 "correct"。一种是建立多对多关系并验证任何 Table 仅在视图中的一个 DiningRoom 中。第二个也是更糟糕的一个可能是为查询集中获得的每个 DiningRoom 获取一次 Tables(但想象一家有 5 或 6 个不同区域(DiningRooms)的餐厅,它需要获取数据库六次每次)。
反之亦然,获取所有 Tables 和 select_related DiningRooms 是不可能的,因为可能有一个没有 Tables 的 DiningRooms(并且在这种情况下,我们将缺少 DiningRooms)。
处理此问题的最佳方法是什么?谢谢!
您可以使用 related_name 或反向关系,一个可接受的解决方案是在 DiningRoom 模型中创建一个名为 associated_tables() 和 return 的方法,使用 related_name(modelname_set,在本例中为 table_set)。是小写子模型的名字后面加上后缀_set
class DiningRoom(models.Model):
#your fields
def associated_tables(self):
return self.table_set.all()
此外,此视频教程可以让您清空一天,让您更好地了解反向关系:
https://youtu.be/7tAZdYRA8Sw
我正在做一个管理餐厅的个人项目。 我的两个模型面临问题,这些模型是 DiningRoom 和 Table.
DiningRoom 表示餐厅可能拥有的任何区域(例如,我们可以在建筑物内部有一个区域,而在建筑物的露台上有其他区域)。 在每个 DiningRoom 中,我们可以设置 Tables.
的布局因此,我发现映射它的更面向对象的方法是通过多对一关系 (ForeignKey)。由于一个DiningRoom可以有多个Table,而一个Table只能在一个DiningRoom中。对吗?
所以我的模型是:
class DiningRoom(models.Model):
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=False)
name = models.CharField(max_length=50, null=False, blank=False)
rows = models.IntegerField(max=15, null=False)
cols = models.IntegerField(max=15, null=False) # rows and columns are for the room's grid layout.
class Table(models.Model):
row = models.IntegerField(max=15, null=False) # The row in the room's grid where the table is at.
col = models.IntegerField(max=15, null=False) # the column in the room's grid where the table is at.
dining_room = models.ForeignKey(DiningRoom, on_delete=models.CASCADE, null=False) # Here is the problem.
问题是,当我在视图中查询帐户的 DiningRoom 时,我还需要获取与查询集结果中每个 DiningRoom 相关的 Tables。
def dining_rooms(request):
try:
account = Account.objects.get(id=request.session['account_id'])
except Account.DoesNotExists:
return response(request, "error.html", {'error': 'Account.DoesNotExists'})
dining_rooms = DiningRoom.objects.filter(account=account)
但我还需要 dining_rooms!
中的 Table 个结果我找到了两个可能的解决方案,但 none 对我来说似乎是 "correct"。一种是建立多对多关系并验证任何 Table 仅在视图中的一个 DiningRoom 中。第二个也是更糟糕的一个可能是为查询集中获得的每个 DiningRoom 获取一次 Tables(但想象一家有 5 或 6 个不同区域(DiningRooms)的餐厅,它需要获取数据库六次每次)。
反之亦然,获取所有 Tables 和 select_related DiningRooms 是不可能的,因为可能有一个没有 Tables 的 DiningRooms(并且在这种情况下,我们将缺少 DiningRooms)。
处理此问题的最佳方法是什么?谢谢!
您可以使用 related_name 或反向关系,一个可接受的解决方案是在 DiningRoom 模型中创建一个名为 associated_tables() 和 return 的方法,使用 related_name(modelname_set,在本例中为 table_set)。是小写子模型的名字后面加上后缀_set
class DiningRoom(models.Model):
#your fields
def associated_tables(self):
return self.table_set.all()
此外,此视频教程可以让您清空一天,让您更好地了解反向关系: https://youtu.be/7tAZdYRA8Sw