2009-12-15 2 views
4

사용자 개체에 ManyToManyField가 있고 사용자가 따르는 사용자를 매핑하는 데 사용됩니다. 나는 그들이 가장 최근에 따라온 사람의 하위 집합 목록을 표시하려고합니다. .order_by()에서 ManyToManyField의 ID로 정렬 할 수있는 트릭이 있습니까? 데이터는 바로 거기에 있습니다.어떻게 장고에서 ManyToManyField의 ID로 정렬 할 수 있습니까?

# (people the user is following) 
following = models.ManyToManyField(User, related_name="following", blank=True) 

theuser.following.filter(user__is_active=True).order_by("user__id") 

이렇게하면 사용자가 따르고 있지만 가입했을 때 주문한 사용자 목록이 표시됩니다. 다음 목록의 순서는 사용자가 따라 한 순서대로하고 싶습니다.

+0

재미 있고 이상한 질문입니다. ManyToMany가 join을하기 위해 사용하는 중간 테이블의 id 필드는 흥미 롭기 때문에 ...? –

+0

일부 코드를 게시하십시오. – czarchaic

+2

@peter 그 테이블에있는 이드는 관계의 순서를 보여 주어 그가 "당신이 최근에 따라 갔다 :"생각을 할 수 있다고 생각합니다. –

답변

0

보통 ManytoManyField으로 이것을 달성 할 수 있는지 확실하지 않습니다. 중간 모델을 명시 적으로 정의 할 수 있습니다.

nb : 테스트되지 않은 코드! 다음과 같이

class Person(models.Model) 
    name = models.CharField(max_length=30) 

class FollowerRelationship(models.Model) 
    follower = models.ForeignKey(Person, related_name = following_set) 
    following = models.ForeignKey(Person, related_name = follower_set) 

그런 다음 쉘에서 다음과 같은 관계를 만들 수 있습니다.

# Create Person objects 
>>> a = Person(name="Alice") 
>>> a.save() 
>>> b = Person(name="Bob") 
>>> b.save() 
>>> c = Person(name="Chris") 
>>> c.save() 

# Let Alice follow Chris and Bob 
>>> FollowerRelationship.objects.create(follower=a, following=c) 
>>> FollowerRelationship.objects.create(follower=a, following=b) 
당신은 라인, 조인 테이블의 ID로 주문 앨리스는 추종자 FollowerRelationship 객체의 검색어 세트를 만들 수 있습니다

:

>>> qs = FollowerRelationship.objects.filter(follower=a).order_by('id') 
>>> [fr.following for fr in qs] 

참고가 FollowerRelationship을 통해 루프가 관계에있는 '따라야'Person을 얻을 수 있습니다.

Django 문서에서 Extra fields on many-to-many relationships을보고 싶을 수도 있습니다.이 문서는 다 대다 관계에서 중간 모델을 지정하는 방법을 설명합니다.

2

방금 ​​관계에 대한 클래스를 만들지 않고이 작업을 수행 할 수있는 방법을 발견했습니다. 출력에 열을 추가 할 수있게 해주는 extra 기능을 사용합니다.

theuser.following.filter(user__is_active=True)\ 
    .extra(select={'creation_seq': 'appname_user_user_following.id'})\ 
    .order_by("creation_seq") 

공지 사항 appname_user_user_following 것을 장고는 내부적으로 작성 관계 테이블의 이름입니다처럼 예에서이 보일 것이다. 그것은 결정 론적이며 메타 메커니즘을 통해 얻을 수 있고 설정할 수 있지만 하드 코딩하는 것이 안전합니다. 여기

가짜 테이블과 열 이름을 내부적으로 생성되고있는 SQL의 예 :

SELECT (appname_user_user_following.id) AS `creation_seq`, `appname_user`.`id` 
FROM `appname_user` INNER JOIN `appname_user_user_following` ON 
(`appname_user`.`id` = `appname_user_user_following`.`user_id`) WHERE 
`appname_user_user_following`.`user_followed_id` = 1 ORDER BY `creation_seq` ASC'; 
+0

그건 나를 위해 일했습니다. dict가 필요하기 때문에 'select'다음에 코드를 중괄호 안에 넣어야합니다. – Archarachne

+1

완료. 감사합니다 @ Archarachne –

1

사실 (적어도 장고 1.10), 당신은 extra 기능을 사용할 필요가 없습니다에 대신 현장에서 직접 주문할 수 있습니다. order_by에 대한 인수로 ".id"다음에 자동으로 생성 된 테이블 이름을 자동으로 사용하십시오. 예 :

theuser.following.filter(user__is_active=True)\ .order_by("appname_user_user_following.id")

다른 많은 솔루션은 테이블을 통해 정의를 생성하고 필드를 추가 제안하지만 당신은 단지별로 정렬하려면 :이 특정 질문에 대한

article.tags.all().order_by('appname_article_tags.id')

pizza.toppings.all().order_by('appname_pizza_toppings.id')

자동으로 생성 된 테이블의 ID는 필요하지 않습니다.