2013-05-22 4 views
8

사용자가 개체 (이 예에서는 영화의 배우)를 "따라갈 수 있도록"django-follow을 사용하고 있습니다.관련 개체 찾기 및 관계 표시

나는

actors_user_is_following = Follow.objects.get_follows(Actor).filter(user=request.user.id) 

를 사용하여 영화 배우의 목록을 후퇴 그러나 나는 또한하고 싶은 사람들은 다음과 같습니다 배우를 기반으로 사용자에게 영화를 제안이다입니다. 이것은 이미 그들이 좋아하는 것과 관련된 영화의 복잡한 알고리즘 일 필요는 없습니다. "이 배우를 따라하고이 배우가이 영화에있어 사용자에게 제안하기 때문에 간단합니다."

나는 이것을 가지고 있습니다. 지금 당장 이걸하는 건데 ...

context['follows'] = { 
     'actors': Follow.objects.get_follows(Actor).filter(user=request.user.id), 
     'genres': Follow.objects.get_follows(Genre).filter(user=request.user.id), 
    } 

    actor_ids = [] 
    for actor in context['follows']['actors']: 
     actor_ids.append(actor.target_artist_id) 

    genre_ids = [] 
    for artist in context['follows']['genres']: 
     genre_ids.append(artist.genre_ids) 

    context['suggested'] = { 
     'films': Listing.objects.filter(Q(actors__in=actor_ids) | Q(genres__in=genre_ids)) 
    } 

어떤 방식으로 작동 하나, 더 좋은 방법이있을 것이라고 확신합니까?

는 가장 중요한 또한 ... 사용자가 다음과 같은 것이 그 특징 배우 또는 장르를 표시하여 추천 된 같은 그 영화 때문에 최종 결과는 같을 이유를 사용자에게 보여주고 싶은

film = { 
title: 'Dodgeball' 
image: '/images/films/dodgeball.jpg' 
followed_actors: ['Ben Stiller', 'Vince Vaughn'] #could be multiple 
followed_genres: ['Comedy'] #could be multiple 
} 

참고 여러 영화를 반환하고 싶습니다. 여기

내 모델은 최대 코딩 방법은 다음과 같습니다

필름 모델과 같이 정의 :

from django.db import models 
from app.actors.models import Actor 
from app.genres.models import Genre 


class Film(models.Model): 
    title = models.CharField(max_length=255) 
    strapline = models.CharField(max_length=255) 
    slug = models.SlugField(max_length=100) 
    image_url = models.CharField(max_length=255) 
    pub_date = models.DateTimeField('date published') 
    actors = models.ManyToManyField(Actor) 
    genres = models.ManyToManyField(Genre) 

    def __unicode__(self): 
     return self.title 

그리고 배우 모델 : 뒤에서

from django.db import models 

from follow import utils 


class Actor(models.Model): 
    title = models.CharField(max_length=255) 
    strapline = models.CharField(max_length=255) 
    image = models.CharField(max_length=255) 
    image_hero = models.CharField(max_length=255) 
    bio = models.TextField() 

    def __unicode__(self): 
     return self.title 


#followable 
utils.register(Actor) 
+0

필름 모델은 어떻게 정의됩니까? – karthikr

+0

@karthikr - 업데이트 된 질문 – kieran

답변

2

, 객체는 기본적으로 많습니다 따라 모델을 등록 할 때마다 필드가 추가 된 일대 다 관계.

당신의 질문은 배우에 대해서만 이야기하지만 코드에는 장르도 포함됩니다. 두 가지를 다 다루는 것이 특히 어렵지는 않습니다. 나는 당신이 원하는 방식이 어느 쪽인지 확실하지 않습니다. 당신이 그들을 사용하기 전에 하위 쿼리를 평가하는 경우

__in lookups의 문서에서 언급 한 바와 같이
films = Film.objects.filter(Q(actors__in=Actor.objects.filter(follow_set__user=request.user)) | 
       Q(genres__in=Genre.objects.filter(follow_set__user=request.user))).distinct() 

가 일부 데이터베이스 백엔드가 더 나은 성능을 제공합니다 :

나는 하나의 검색어에 영화 객체를 얻을 수 있다고 생각

actor_ids = list(Actor.objects.filter(follow_set__user=request.user).values_list('id', flat=True)) 
genre_ids = list(Genre.objects.filter(follow_set__user=request.user).values_list('id', flat=True)) 
films = Film.objects.filter(Q(actors__in=actor_ids) | Q(genres__in=genre_ids)).distinct() 

일치하는 필름 만 반환하려는 경우 그 필름을 표현하는 가장 간결한 방법이라고 생각합니다.

필름에 이유를 추가하는 부분에서는 필름 쿼리 세트를 반복하고 수동으로 정보를 추가하는 것보다 더 세련된 방법을 보지 못합니다. 나는 확실히 그것을하기 전에 actor_ids와 genre_ids에 대한 querysets를 정의 할 것이지만, 나는 그것들을 일찍 평가했는지 여부는 여전히 db 백엔드에 달려있다.

annotated_films = [] 
for film in films: 
    film.followed_actors = film.actors.filter(id__in=actor_ids) 
    film.followed_genres = film.genres.filter(id__in=genre_ids) 
    annotated_films.append(film)