How to show if a custom instance of an object in Django

I have the following table in my Django model, Utensils and Campaigns. On my homepage, I show a list of all the dishes in the database, and I have a button on each dish. For dishes that the user liked, I want to indicate that they already liked them, so that they can be different from them and vice versa. I have tried different approaches over the past few days, but I canโ€™t understand anything. Here is the code for my last failed attempt.

#dishes table class Dishes(models.Model): name = models.CharField(max_length=40, unique=True) def liked(dish, user): try: user_upvoted = Likes.objects.get(dish=dish, user=user) except: user_upvoted = None if user_upvoted: return True else: return False #upvotes class Likes(models.Model): dish = models.ForeignKey(Dishes) user = models.ForeignKey(User) date_added = models.DateTimeField(auto_now_add=True) def home(request): this_user = auth.models.User.objects.get(id=1) dishes = models.Dishes.objects.all() for dish in dishes: models.Dishes.voted(dish, this_user) `enter code here`return render_to_response('frontend/home.html', { 'dishes': dishes, }) 
+4
source share
2 answers

Adding ManyToMany solves this problem:

 class Dishes(models.Model): name = models.CharField(max_length=40, unique=True) likes = models.ManyToManyField(Likes) class Likes(models.Model): dish = models.ForeignKey(Dishes) user = models.ForeignKey(User) date_added = models.DateTimeField(auto_now_add=True) 

Adjust your presentation as follows:

 from django.contrib.auth.decorators import login_required from django.shortcuts import render @login_required def home(request): dishes = Dishes.objects.all() return_list = [] for dish in dishes: return_list.append((dish, dish.likes_set.filter(user=request.user))) return render(request, 'dish_list.html', {'dishes': return_list}) 

Your template uses a "switch":

  {% for dish, liked in dishes %} {{ dish.name }} {% if liked %} You already like this dish. {% else %} Like this dish now, its yummy! {% endif %} {% endfor %} 

Or, if you cannot change your model, edit your view code as follows:

 @login_required def home(request): dishes = Dishes.objects.all() return_list = [] for dish in dishes: return_list.append((dish, Likes.objects.filter(user=request.user, dish=dish))) return render(request, 'dish_list.html', {'dishes': return_list}) 

The idea is that the list of objects that you return to the template is already marked for the user who is logged in.

login_required decorator ensures that the view is called only when the user logs in. Otherwise, it redirects the user to the login page.

render shortcut ensures that RequestContext always passed from your views.

+2
source

You need a new model and it is assumed that you are using the django user model, you might have something like this:

models.py

 from django.contrib.auth.models import User class DishLiked(models.Model): dish = models.ForeignKey(Dish, related_name='liked_by' ) like = models.ForeignKey(Like, related_name='like_by' ) user = models.ForeignKey(User, related_name='liked_dishes' ) 

views.py

Note. Also note that they are a way to get the user from request :

 def home(request): user = request.user liked = DishLiked.objects.filter( user__id=user.id ) dish_id_list = [] for liked_dish on liked: dish_id_list.append(liked_dish.dish.pk) dishes_liked_by_user = Dish.objects.filter(id__in=dish_id_list) 
0
source

Source: https://habr.com/ru/post/1501232/


All Articles