2013-05-22 16 views
8

Kullanıcıların "takip et" nesnelerini kullanmasına izin vermek için django-follow kullanıyorum. Bu örnekte, filmdeki Aktörler.İlgili nesneleri ve görünen ilişkiyi bul

Ben

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

kullanılarak film aktörlerin listesini geri çekerek Ama benim de yapmak istediğim onlar takip ediyor aktörler dayalı kullanıcıya filmleri önermek olduğunu duyuyorum. Bu zaten ne gibi ve karmaşık filmler öneren karmaşık bir algoritma olmak gerekmez, sadece bir "bu aktör izleyin ve bu aktör bu filmde, kullanıcı için önermek", kullanıcı için önermek "

Bunun yerine Bunu şu anda yapmanın tıknaz yolu ...

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

Hangi işe yarar, ama eminim ki bunu yapmanın daha iyi bir yolu var mı?

En önemlisi Ben de ... kullanıcı takip ediyor o özellikleri aktörler veya türler göstererek tavsiye olarak bu filmin, bu nedenle sonuç gibi bir şey olabilir Kullanıcıya neden göstermek istiyorum

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

Not Birden çok film dönmek istiyorum. İşte

benim modeller kadar kodlanmış olduğu anlatılmaktadır:

Film Modeli şöyle tanımlanır:

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 

Ve Aktör Modeli: Sahne arkası

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

nasıl film modeli tanımlanır? – karthikr

+0

@karthikr - güncellenmiş soru – kieran

cevap

2

, nesneler esasen çoktur izleyin modele her kaydettiğinizde alanlar ile çok fazla ilişki eklendi.

Sorunuz sadece aktörler bahsediyor, ama sizin kodu da türler içermektedir. Her ikisini de kapsayacak şekilde özellikle zor değil, sadece istediğiniz gibi bir yol olduğundan emin değilim. Bunları kullanmadan önce alt sorgular değerlendirmek eğer

__in lookups için docs belirtildiği gibi
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() 

, bazı veritabanı geri uçları size daha iyi performans verecektir:

Sana bir sorgu kümesi içinde filmin nesneleri alabilirsiniz düşünmek

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

Sadece eşleşen filmleri iade etmek istiyorsanız, bunların en açık yolu olduğunu düşünüyorum. Eğer filmlere nedenlerini ekliyoruz kısmı için

- Ben elle bilgi eklemek QuerySet ve filmler arasında yineleme daha o işlemek için daha şık bir yol göremiyorum. Actor_ids ve genre_ids için querysets'leri kesinlikle tanımlamam gerekirdi, her ne kadar bunları değerlendirip incelemediğim de yine de db arka ucuna bağlı olacaktır.

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)