2017-09-13 7 views
0

je le modèle suivant avec un champ m2m où les utilisateurs enregistrés peuvent intéresser à une publication:Vérifiez si l'utilisateur est dans le domaine Many2Many

models.py

from django.db import models 

class Publication: 
    title = models.CharField(max_lenth=512) 
    users_interested = models.ManyToManyField(User) 

views.py

from django.shortcuts import render 
from django.views import View 
from .models import Publication 

class listPublicationView(View): 
    def get(self, request, *args, **kwargs): 

    publications = Publication.objects.all() 

    return render(request, "base.html", {'publications': publications}) 

maintenant, j'essaie de produire un « Je suis déjà intéressé » dans le modèle lorsqu'un connecté l'utilisateur est déjà intéressé par la publication:

base.html

{% for publication in publications %} 

    {{publication.title}} 

    {% if currently logged in User is interested in publication (check users_interested) %} 
     i am already interested 
    {% endif %} 

{% endfor %} 

Je pense à quelque chose comme ceci:

{% if user.id in publication.users_interested__id %} 
+0

Vous devez charger les informations que vous voulez dans votre vue. Le template n'est pas là pour produire quoi que ce soit (mais html, ofc). Dans votre cas, probablement une forme de 'prefetch_related()' ou 'annotate()'. – spectras

Répondre

1

Cela semble ressembler à une bonne solution:

models.py

from django.db import models 

class Publication: 
    title = models.CharField(max_lenth=512) 

    #added a reverse accessor 
    users_interested = models.ManyToManyField(User, related_name='users_interested') 

view.py

from django.shortcuts import render 
from django.views import View 
from .models import Publication 

class listPublicationView(View): 
    def get(self, request, *args, **kwargs): 

    publications = Publication.objects.all() 

    # create a set of group IDs that this user is a part of 
    current_user = request.user 
    user_publication_set = set(current_user.users_interested.values_list('id', flat=True)) 

    #pass set to template 
    return render(request, "base.html", {'publications': publications, 'user_publication_set': user_publication_set}) 

base.html

{% for publication in publications %} 

    {{publication.title}} 

    {% if publication.id in user_publication_set %} 
     i am already interested 
    {% endif %} 

{% endfor %} 

trouvé cette solution dans Django: check for value in ManyToMany field in template

+0

C'est une bien meilleure solution en effet. Le point est de toujours avoir la vue déterminer quelles données doivent être chargées, de sorte qu'il peut contrôler la logique. C'est exactement ce que vous avez fait. – spectras

0

Essayez comme ceci:

{% if request.user in publication.users_interested.all %} 
  • request.user propriété contient le courant utilisateur connecté
  • Ensuite, vous utilisez l'opérateur in avec publications.users_interested.all() (Notez qu'il n'y a pas entre parenthèses sur .all() dans le modèle
+1

Et avec ceci dans la boucle dans son modèle, s'il a, disons, 1000 publications, sa page écrase soudainement la base de données avec 1001 requêtes. – spectras

+0

cela fonctionne - mais je vais vraiment avoir quelques centaines de publications –