使用Django的内置模型,如何在三个模型之间创建三重连接。
例如:
如何在模型中表示?
答案 0 :(得分:8)
zacherates 写道:
我将角色建模为用户和角色(...)之间的关联类
我也推荐这个解决方案,但你也可以使用Django提供的一些语法糖:ManyToMany relation with extra fields。
示例:
class User(models.Model):
name = models.CharField(max_length=128)
class Event(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(User, through='Role')
def __unicode__(self):
return self.name
class Role(models.Model):
person = models.ForeignKey(User)
group = models.ForeignKey(Event)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
答案 1 :(得分:3)
我建议只为此创建一个完全独立的模型。
class Assignment(Model):
user = ForeignKey(User)
role = ForeignKey(Role)
event = ForeignKey(Event)
这可以让你做所有常用的模型,比如
user.assignment_set.filter(role__name="Chaperon")
role.assignment_set.filter(event__name="Silly Walkathon")
唯一剩下的就是强制执行每个用户每个用户一个角色的限制。您可以通过覆盖保存方法(http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods)或使用信号(http://docs.djangoproject.com/en/dev/topics/signals/)
在Assignment类中执行此操作答案 2 :(得分:0)
我将角色建模为用户和角色之间的关联类,因此,
class User(models.Model):
...
class Event(models.Model):
...
class Role(models.Model):
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
并在管理员或SQL约束中为每个事件强制执行每个用户一个角色。
答案 3 :(得分:0)
在尝试为我自己的Django模型找到更快的三表连接时,我遇到了这个问题。默认情况下,Django 1.1使用INNER JOIN,这在InnoDB上可能很慢。对于像这样的查询:
def event_users(event_name):
return User.objects.filter(roles__events__name=event_name)
这可能会创建以下SQL:
SELECT `user`.`id`, `user`.`name` FROM `user` INNER JOIN `roles` ON (`user`.`id` = `roles`.`user_id`) INNER JOIN `event` ON (`roles`.`event_id` = `event`.`id`) WHERE `event`.`name` = "event_name"
与LEFT JOIN相比,INNER JOIN可能会非常慢。在gimg1的答案下可以找到更快的查询:Mysql query to join three tables
SELECT `user`.`id`, `user`.`name` FROM `user`, `roles`, `event` WHERE `user`.`id` = `roles`.`user_id` AND `roles`.`event_id` = `event`.`id` AND `event`.`name` = "event_name"
但是,您需要使用自定义SQL查询:https://docs.djangoproject.com/en/dev/topics/db/sql/
在这种情况下,它看起来像:
from django.db import connection
def event_users(event_name):
cursor = connection.cursor()
cursor.execute('select U.name from user U, roles R, event E' \
' where U.id=R.user_id and R.event_id=E.id and E.name="%s"' % event_name)
return [row[0] for row in cursor.fetchall()]