Django get user like from friend list - python

I'm a Django beginner, I have a friend field in Profile Model which list all my friend users. And also these friends liked my post. How do I get the names of only those users in my friends list to display in the post they liked.
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,... )
friends = models.ManyToManyField('Profile',related_name='my_friends')
class FriendRequest(models.Model):
to_user = models.ForeignKey(settings.AUTH_USER_MODEL,... )
from_user = models.ForeignKey(settings.AUTH_USER_MODEL,... )
class Post(models.Model):
poster_profile = models.ForeignKey(settings.AUTH_USER_MODEL,... )
likes = models.ManyToManyField(User, related_name='image_likes')
def home(request):
all_images = Post.objects.filter(poster_profile=request.user)
img = Post.objects.filter(likes__profile__friends__user=request.user)
{% if all_images %}
{% for post in all_images %}
#all_images code here
{{ post. likes.count }} #like count
{% for image in img %}<img src="{{ image.profile.profile_pic.url }}"> {% endfor %}#The profile_pic do not display
{% endfor %}
{% endif %}

if someone isn't your friend you can prevent him to like or even see (or comment) your post , or for each user who likes your post check if he is in your friend list then add him to a new emty list then render this list

Change your queryset in your view to this:
from django.db.models import Count, Q
all_images = Post.objects\
.filter(poster_profile=request.user)\
.annotate(likes_count=Count(
'likes',
distinct=True,
filter=Q(likes__profile__friends=request.user.profile))
then in your template each post has the annotation likes_count so you can do {{ post.likes_count }}.

Related

How do I filter a model in html django

I'm trying to filter a model in HTML I know that you can use eg. Model.objects.filter(bla=bloo, ...).
I wanna do that in HTML not in my views.py.
my model looks like this:
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="likeUser")
post = models.ForeignKey(NewPost, on_delete=models.CASCADE)
heres my views.py:
posts = NewPost.objects.all()
like = Like
return render(request, "network/index.html", {
"posts": posts,
"like": like
)}
heres what I'm trying to do in HTML:
{% for post in posts %}
{{ like.objects.filter(post=post) }}
{% endfor %}
I'm getting an error right now saying: Could not parse the remainder: '(post=post)' from 'like.objects.filter(post=post)'
How can I make it work?
According to the docs, a reverse relation is created by default, so you can simply do:
{% for post in posts %}
{{ post.like_set }}
{% endfor %}

How to access model.field in template? django

I started learning django few days ago and trying to build my first blog.
My problem is that I decided to add an extra field for my categories (subheading), which I want to be in my template, but can't understand how to do it.
my models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
subheading = models.CharField(max_length=160)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
link = models.TextField()
categories = models.ManyToManyField("Category", related_name="posts")
def __str__(self):
return self.title
views.py
from django.shortcuts import render
from blog.models import Post, Category
def blog_category(request, category):
posts = Post.objects.filter(
categories__name__contains=category
).order_by(
'title'
)
context = {
"category": category,
"posts": posts
}
return render(request, "blog_category.html", context)
The only way category.name or category.subheading are displayed in template (by the teacher) is inside {% for post in posts %} {% endfor %}:
{% for post in posts %}
{% for category in post.categories.all %}
{{ category.subheading }}
{% endfor %}
{% endfor %}
In this case, if there are 10 posts on category page, subheading repeats 10 times. I only need to print 1 to describe category.
Is there a way to call category.subheading outside of {% for post in posts %} ? Or somehow to print only one result.
p.s. sorry for my primitive English level.
You can do this with a Prefetch object [Django-doc]:
from django.db.models import Prefetch
def blog_category(request, category):
posts = Post.objects.filter(
categories__name__contains=category
).prefetch_related(
Prefetch(
'categories',
Category.objects.filter(name__contains=category)
to_attr='relevant_categories'
)
).order_by(
'title'
)
# …
In your template, you can then render this with:
{% for post in posts %}
{% for category in post.relevant_categories %}
{{ category.subheading }}
{% endfor %}
{% endfor %}
Not sure to understand what you want to do but you can search and access to Category elements by doing something like that:
categories=Category.objects.filter(name='NameYouWanttoSearch').values_list('subheading')
can add a model manager to the categories , take single instance and call it in templates instead of all.
class CategoryManager(models.Manager):
def single_category(self):
return self.get_queryset()[:1]
class Category(models.Model):
name = models.CharField(max_length=20)
subheading = models.CharField(max_length=160)
objects = CategoryManager()
def __str__(self):
return self.name
and in templates
{% for post in posts %}
{% for category in post.categories.single_category %}
{{ category.subheading }}
{% endfor %}
{% endfor %}

Listing ForeignKey associated instances within template (queryset within a queryset)

I have a site which catalogs local hikes, and users can log that they have been on the hike. I have a search page which contains the hikes, and one of the fields I'm trying to display is a list of all the people who have been on the hike. I've got this figured out within the individual detail page of the hike, but can't figure out how to create a new queryset within the queryset which is printing the hikes, in order to display this info on a search page.
Here's some code:
models.py:
class Hike(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(unique=True)
...
class UserLog(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
hike = models.ForeignKey(Hike, on_delete=models.CASCADE)
views.py:
def hike_list(request):
qs = Hike.objects.all()
... some other filters here
?-->users = UserLog.objects.filter(id=qs.id)
template:
{% for qs in qs %}
{{ hike.name }}{{ hike.other_details_and_stuff }}
?----> {% for users in hikes %}{{ user.name }}{% endfor %}
{% endfor %}
Here's the working code within the individual hike's detail page:
views.py:
def hike_detail (request, slug)
users = UserLog.objects.filter(hike__slug=slug)
How do I call on the slug from each individual item in the queryset, then run a queryset on that?
The easiest is to add a ManyToManyField to Hike:
class Hike(models.Model):
...
users = models.ManyToManyField(User, through='app.UserLog')
If you have no extra fields in UserLog, you can even remove the UserLog model and the through parameter alltogether. In the template you can do:
{% for hike in qs %}
{{ hike.name }}{{ hike.other_details_and_stuff }}
{% for user in hike.users.all %}{{ user.name }}{% endfor %}
{% endfor %}
In order avoid too many queries, you should prefetch the users in the Hike query in the view:
qs = Hike.objects.all().prefetch_related('users')
Without the ManyToManyField, you could add a property and user the same template, but the prefetch clause could not be used that easily:
class Hike(models.Model):
...
#property
def users(self):
return User.objects.filter(userlog__hike=self)

Django: Check that row exists in list

I want to check that user_id exists in the profile_images table from my Django template.
My Model
class profiles(models.Model):
profile_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
-----
class Profile_images(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
image = models.ImageField(upload_to='uploads/',default = 'uploads/no-img.jpg')
My View
def view_profiles(request):
if request.user.is_authenticated():
view_all_profiles = profiles.objects.all()
profile_image = Profile_images.objects.all()
return render_to_response('profiles/all.html', {'profiles':view_all_profiles,'profile_image':profile_image}, context_instance=RequestContext(request),)
else:
return HttpResponseRedirect('/accounts/login/')
My Template
{% for profile in profiles %}
<li>
{% for image in profile_image %}
{% ifequal image.user_id profile.user_id %}
<img src="{{MEDIA_URL}}{{image.image}}" alt="image" />
{% endifequal %}
<!-- i want to check here if not user_id exist in profile_images table -->
{% if profile.user_id not in profile_image %}
<img src="{% static 'images/no-image.jpg' %}" alt="image" />
{% endif %}
{% endfor %}
</li>
{% endfor %}
{% if profile.user_id not in profile_image %} is not working. I'm new to Django & python and I'm stuck here. Please suggest better ways if my code is not correct.
in your view you could get all user_ids with a profile image, something like:
user_ids_with_profile_images = Profile_images.objects.all().values_list('user_id', flat=True)
Then in your template you could check if profile.user_id not in user_ids_with_profile_images.
It might actually be a little cleaner to loop through all the users with profiles in your system and get their profile images through the foreign key, instead of looping through all the profiles and trying to get the users...
This is really a design problem, you've got a separate model specifically for a profile image when that could just be a field on the profile model itself.
class Profile(models.Model): # convention is to use a non-plural name for models
# No need to explicitly set the primary key, this will be added automatically
# profile_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
image = models.ImageField(upload_to='uploads/',default = 'uploads/no-img.jpg')
-----
Now it would just be a case of using {{ profile.image }} with no need for any additional looking up.

Django, revover a model with multi foreign key

I would like to show all favorites of connected user.
Each user can add his own favorites. I created a model to manage this action.
In this one, I have two foreign key. One for the user and the second for the "favorite".
models.py
class Favorite(models.Model):
user = models.ForeignKey(User)
drud = models.ForeignKey(Drud)
def __unicode__(self):
return self.drud.secure_key
On my view, I want to show all favorite Drud of connected user. I tried to do something like that:
views.py
favorite = Favorite.objects.filter(drud=[d.secure_key for d in Drud.objects.filter(user=request.user)])
But, that does work...
You can do:
fav_druds = request.user.favorite_set.values_list('drud', flat=True)
In the template you can do:
{% for drud in fav_druds %}
{{drud.id}}: {{drud.secure_key}}
{% endfor %}
Edit:
favs = request.user.favorite_set.all()
{% for fav in favs %}
{{fav.drud.id}}: {{fav.drud.secure_key}}
{% endfor %}

Categories