2009-08-16 7 views
2

J'ai un modèle de livre qui peut être ajouté aux favoris de l'utilisateur. Donc, je définissais 2 classes:Demande d'utilisateur modèle Django


class Book(models.Model): 
    name = models.CharField(max_length = 40) 

class UserFavorite(models.Model): 
    book = models.ForeignKey(Book) 
    user = models.ForeignKey(User) 

Maintenant, je voudrais montrer sur la page principale des livres populaires avec une icône soit « ajouter aux favoris » ou « des favoris ». Fondamentalement, je passe tableau de livres populaires à un modèle et à partir du modèle je boucle à travers ce tableau et devrait dire "if book.is_in_favorites (request.user): ...", mais ce n'est pas possible à partir du modèle.

Répondre

3

L'approche la plus courante consiste à décorer les objets du livre dans la vue. Dans le code de la vue, boucle sur les livres, en ajoutant une valeur booléenne indiquant si elles sont un favori de l'utilisateur actuel ou non:

for b in books: 
    b.is_fav = b.is_in_favorites(request.user) 

puis dans le modèle:

{% for b in books %} 
    blah blah {{b.blah}} 
    {% if b.is_fav %}FAVORITE INDICATOR{% endif %} 
{% endfor %} 

Si vous n'êtes pas comme la modification des objets de livre, vous pouvez faire une liste de dicts qui enveloppe les livres avec leurs annotations:

book_info = [{'book':b, 'is_fav':b.is_in_favorites(request.user)} for b in books] 

et de l'utiliser dans votre modèle:

{% for bi in book_info %} 
    blah blah {{b.book.blah}} 
    {% if bi.is_fav %}FAVORITE INDICATOR{% endif %} 
{% endfor %} 
+0

1) Dois-je définir is_fav dans le modèle Book? Ou cela va ajouter un champ "à la volée"? 2) L'approche est correcte, bien qu'il faut exécuter plusieurs instructions select (une pour tous les livres, puis une pour chaque livre pour is_fav), ce qui affecte les performances. Peut-être y at-il un moyen de le faire avec seulement 1 requête qui obtient tous les livres? – Vitaly

+0

En fait, j'ai trouvé qu'il y a "extra" clause qui peut ajouter des propriétés à la volée, je vais essayer de l'utiliser – Vitaly

+0

Si vous voulez éviter les recherches répétées causées par l'instruction for (et puisque select_related * ne sera pas * aider ici) vous appelez UserFavorites.objects.filter (utilisateur = request.user) et comparez votre itération des livres à l'ensemble des UserFavorites renvoyés. Ensuite, il n'y a que 2 hits DB. –

1

Je ne comprends pas ce que cela a à voir avec les modèles. Vous avez juste besoin d'afficher un lien vers une vue qui prend l'identifiant du livre en paramètre, extrait l'utilisateur de la requête et ajoute un UserFavourite en utilisant les deux.

Mise à jour après modification: OK, je comprends votre problème maintenant. Eh bien, comme vous l'avez constaté, ce genre de chose est trop complexe pour être intégré dans la logique du modèle. Il faut vraiment aller soit dans votre vue, ou dans une balise de modèle. Probablement un tag de modèle est le meilleur, car vous voudrez sans aucun doute utiliser cette fonctionnalité dans plusieurs vues/modèles.

Vous voudrez probablement utiliser une balise d'inclusion, car cela a l'avantage de pouvoir prendre le contexte automatiquement. Quelque chose comme (non testé):

@register.inclusion_tag('add_to_favourites.html', takes_context=True) 
def favourite_links(context): 
    user = context['request'].user 
    books = Book.objects.exclude(userfavourite__in=user) 
    return {'books': books, 'user':user} 

Maintenant, vous avez juste besoin d'un fragment de modèle qui rend une liste en utilisant les valeurs dans les livres retournés par l'étiquette ci-dessus. Et dans votre modèle principal, utilisez simplement favourite_links pour afficher les liens du livre.

+0

Fondamentalement, je passe un tableau de livres populaires à un modèle de la vue principale. Maintenant, à partir du modèle, je fais une boucle à travers ce tableau et je dois dire "comme book.is_in_favorites (request.user)" - ce qui n'est pas possible de cette façon. Je ne m'inquiète pas pour l'instant comment implémenter la vue qui ajoutera ce livre dans les favoris. – Vitaly

Questions connexes