문제

Django의 내장 모델을 사용하여 어떻게 세 모델 사이에 삼중 조인을 생성할 수 있습니까?

예를 들어:

  • 사용자, 역할 및 이벤트가 모델입니다.
  • 사용자에게는 많은 역할이 있고 역할에는 많은 사용자가 있습니다.(다대다)
  • 이벤트에는 많은 사용자가 있고 사용자에는 많은 이벤트가 있습니다.(다대다)
  • 그러나 특정 이벤트에 대해 모든 사용자는 하나의 역할만 가질 수 있습니다.

이것이 모델에서 어떻게 표현될 수 있나요?

도움이 되었습니까?

해결책

자케라테스 쓴다:

나는 사용자와 역할 사이의 연관 클래스로 역할을 모델링하겠습니다(...)

나는 또한 이 솔루션을 추천하지만 Django에서 제공하는 몇 가지 구문적 설탕을 사용할 수도 있습니다. 추가 필드와 ManyToMany 관계.

예:

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)

다른 팁

이를 위해 완전히 별도의 모델을 만드는 것이 좋습니다.

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-predefed-model-methods) 또는 신호를 사용하여(http://docs.djangoproject.com/en/dev/topics/signals/)

나는 사용자와 역할 사이의 연관 클래스로 역할을 모델링할 것입니다.

class User(models.Model):
     ...

class Event(models.Model):
     ...

class Role(models.Model):
     user = models.ForeignKey(User)
     event = models.ForeignKey(Event)

그리고 관리자 또는 SQL 제약 조건에서 이벤트당 사용자당 하나의 역할을 적용합니다.

내 Django 모델에 대한 더 빠른 3개 테이블 조인을 찾으려고 노력하는 동안 이 질문을 발견했습니다.기본적으로 Django 1.1은 InnoDB에서 속도가 느릴 수 있는 INNER JOIN을 사용합니다.다음과 같은 쿼리의 경우:

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"

INNER JOIN은 LEFT JOIN에 비해 매우 느릴 수 있습니다.gimg1의 답변에서 더 빠른 쿼리를 찾을 수 있습니다. 세 개의 테이블을 조인하는 MySQL 쿼리

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()]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top