2013-05-22 62 views
8

我使用django-follow来允许用户“关注”对象 - 在本例中为电影中的Actor。查找相关对象并显示关系

我使用

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

在幕后,按照对象基本上是一个不少每次注册模型时添加的字段与多对多的关系。

你的问题只是谈论演员,但你的代码还包括类型。覆盖两者并不难,我只是不确定你想要的方式。

我认为你可以在一个查询集你的电影对象:

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() 

如文档注意到__in lookups,一些数据库后端会,如果你在使用前评估子查询给你更好的性能:

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定义查询集,尽管我是否提前评估它们仍然取决于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)