auth.user.none and <QuerySet []> in ManyToManyField rendering - python

I try to display numbers of Users who liked some image on my website written in Django.
The Image model looks like this below:
class Image(models.Model):
(***)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='images_liked',
blank=True)
When I use in my template:
{{image.users_like.all}}
I get :
QuerySet [],
when I use in templates
{{image.users_like}}
I get
auth.User.None.
It's weird because in my admin page I have information that someone liked this photo.
Below my view function:
def image_detail(request, id, slug):
image = get_object_or_404(Image, id=id, slug=slug)
return render(request,
'images/image/detail.html',
{'section': 'images',
'image': image})
EDIT
My admin page, in Users like section display usernames of user who already liked the photo. PrtSc below:
FULL BLOCK
<h1>{{ image.title }}</h1>
`<p>{{image.users_like.all}}</p>
{% load thumbnail %}
{% thumbnail image.image "300" as im %}
<a href="{{ image.image.url }}">
<img src="{{ im.url }}" class="image-detail">
</a>
{% endthumbnail %}
{% with total_likes=image.users_like.count users_like=image.users_like.all %}
<div class="image-info">
<div>
<span class="count">
<span class="total">{{ total_likes }}</span>
like{{ total_likes|pluralize }}
</span>
<a href="#" data-id="{{ image.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
{% if request.user not in users_like %}
Like
{% else %}
Unlike
{% endif %}
</a>
</div>
{{ image.description|linebreaks }}
</div>
<div class="image-likes">
{% for user in image.users_like.all %}
<div>
<img src="{{ user.profile.photo.url }}">
<p>{{ user.first_name }}</p>
</div>
{% empty %}
Nobody likes this image yet.
{% endfor %}
</div>
{% endwith %}

Answer in the comments above. QuerySet was empty when called. After adding users to image.users_like the problem disappeared. Thank you solarissmoke.

Related

Trying to show model data on web page by using ListView. Its not working

I created the model post and I want to show all the posts on Web Page using Class-based views but It's not working. the URL is opening but the web page is not showing anything( stuff that is on homepage.html and on _post.html but navbar is there which is coming from _inject.html). The problem is in coding in the template.
Post Model-
class Post(models.Model):
auther = models.ForeignKey(User, related_name="posts",on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now=True)
heading = models.CharField(max_length=400)
message = models.TextField()
message_html = models.TextField(editable=False)
def __str__(self):
return self.message
def save(self,*args,**kwargs):
self.message_html = misaka.html(self.message)
super().save(*args,**kwargs)
def get_absolute_url(self):
return reverse('posts:single',kwargs={'username':self.user.username,'pk':self.pk})
class Meta:
ordering = ['-created_at']
unique_together = ['auther','message']
Post view-
class ListPosts(generic.ListView):
model = models.Post
template_name = "homepage.html"
homepage.html
{% extends "_inject.html" %}
{% block content %}
<div class="col-md-8">
{% if post.count == 0 %}
<h2>No posts in this group yet!</h2>
{% else %}
<ul>
{% for p in Post.all %}
<h1>p.message</h1>
<li> {% include "_post.html" %} </li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}
_post.html-
<div class="media">
<h3 class="mr-5">#{{ post.user.username }}</h3>
<div class="media-body">
<strong>{{ p.user.username }}</strong>
<h5>{{ p.message_html|safe }}</h5>
<time class="time">{{ p.created_at }}</time>
<div class="media-footer">
{% if user.is_authenticated and post.user == user and not hide_delete %}
<a href="{% url 'posts:delete' pk=post.pk %}" title="delete" class="btn btn-simple">
<span class="fa fa-remove text-danger" aria-hidden="true"></span>
<span class="text-danger icon-label">Delete</span>
</a>
{% endif %}
</div>
</div>
</div>
Try changing your homepage.html to something like this:
{% extends "_inject.html" %}
{% block content %}
<div class="col-md-8">
{% if post_list %}
{% for post in post_list %}
<h1>{{post.message}}</h1>
<li>{% include "_post.html" %} </li>
{% endfor %}
{% else %}
<h2>No posts in this group yet!</h2>
{% endif %}
</div>
{% endblock %}

Display user's posts in their profile on django

I have been trying to make the profile page of a user have the user's posts but everytime I run my code nothing shows up only the user's username and user's email. I've tried multiple ways to make it work but somehow it doesn't. I think the profile.html has the error in it.
views.py
def profile(request, pk=None):
if pk:
post_owner = get_object_or_404(User, pk=pk)
user_posts=Post.objects.filter(posti=request.user)
else:
post_owner = request.user
user_posts=Post.objects.filter(posti=request.user)
return render(request, 'profile.html', {'post_owner': post_owner, 'user_posts': user_posts})
models.py
class Post(models.Model):
text = models.CharField(max_length=200)
posti = models.ImageField(upload_to='media/images', null=True, blank="True")
user = models.ForeignKey(User, related_name='imageuser', on_delete=models.CASCADE, default=2)
profile.html
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ post_owner.username }}</h2>
<p class="text-secondary">{{ post_owner.email }}</p>
</div>
{% for Post in user_posts %}
<li class="list-group-item">{{ Post.text }}
{{ Post.user }}
{% if Post.posti %}
<img src="{{ image.posti.url }}" alt="image here" style="max-width: 300px; max-height: 300px">
{% endif %}
{% if Post.user == user %}
<div class="float-right">
<form action="delete_image/{{ image.id }}/" action="post">
<button type="submit" class="btn btn-outline-danger btn-sm">Delete</button>
</form>
</div>
{% endif %}
</li>
{% endfor %}
</div>
</div>
The problem here is with the line:
user_posts=Post.objects.filter(posti=request.user)
To get the posts from the logged in user you will need to use this:
user_posts=Post.objects.filter(user=request.user)
and to get the posts from the selected user you will need to do this:
user_posts=Post.objects.filter(user_id=pk)
I hope this helps :)
You are querying the wrong column:
user_posts=Post.objects.filter(posti=request.user)
posti is an ImageField. You actually want to query the user field:
user_posts=Post.objects.filter(user=request.user)
That being said, you don't need any of these queries in your view. You can simply make use of your related_name, i.e.:
{% for Post in post_owner.imageuser.all %}

Django: displaying foreign key model in parent model's detail view template

I have the following two models:
class SpecimenImage(models.Model):
image = ImageField(upload_to='images/')
usi_image = models.ForeignKey('SpecimenRecord', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='Unique Specimen Identifier')
...
class SpecimenRecord(models.Model):
usi = models.CharField(primary_key=True, max_length=20, verbose_name='Unique Specimen Identifier')
species = models.ForeignKey(Species, on_delete=models.SET_NULL, null=True, blank=True)
locality = models.ForeignKey(Locality, on_delete=models.SET_NULL, null=True, blank=True)
date = models.DateField(null=True, blank=True)
collector = models.ManyToManyField(Collector, verbose_name='Collector(s)', null=True, blank=True)
...
I have a generic detail view for SpecimenRecord:
...
class SpecimenDetailView(generic.DetailView):
model = SpecimenRecord
Here is the urls.py:
...
urlpatterns = [
...
path('specimen/<str:pk>', views.SpecimenDetailView.as_view(), name='specimen-detail'),
]
My question is, how do I display and loop through all of the SpecimenImage instances associated with a single SpecimenRecord object in the html template? I can easily display the information for each SpecimenRecord by using {{ specimenrecord.usi }}, etc., but I cannot figure out how to display each image.
I've tried using the information on the MDN website for generic detail views (https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views):
{% for copy in book.bookinstance_set.all %}
<!-- code to iterate across each copy/instance of a book -->
{% endfor %}
Here is the code I tried in my template specimenrecord_detail.html:
{% extends "base.html" %}
{% load thumbnail %}
{% block content %}
...
{% for copy in specimenrecord.specimenimage_set.all %}
<div class="gallery">
<img src="{% thumbnail copy.image '1920' as im %}{{ im.url }}{% endthumbnail %}" alt="specimen image"
srcset="
{% thumbnail copy.image '544' as im %} {{ im.url }} {{ im.x }}w{% endthumbnail %},
{% thumbnail copy.image '768' as im %} {{ im.url }} {{ im.x }}w{% endthumbnail %},
{% thumbnail copy.image '992' as im %} {{ im.url }} {{ im.x }}w{% endthumbnail %},
{% thumbnail copy.image '1200' as im %} {{ im.url }} {{ im.x }}w{% endthumbnail %},
{% thumbnail copy.image '1920' as im %} {{ im.url }} {{ im.x }}w{% endthumbnail %}"
alt="specimen image"
sizes="100vw"
/>
</div>
{% endfor %}
{% endblock %}
However, this code yielded an empty <div>. What am I doing wrong?
After playing around with the code, I found a solution. By wrapping the code below around the <img src>, the images appear in the div:
<a target="_blank" href="{{ copy.image.url }}">
<img src=.....>
</a>
(I'm not sure why this works, but I'm glad I got the result I wanted.)

Django class based view pagination not working

I am trying to use a pagination to paginate one of my pages. I have tried a few different methods I have found online but for some reason, when I use paginate_by = 3, it doesn't actually paginate anything, yet still shows the html for the pagination at the bottom of the page.
View:
class SearchListView(ListView):
model = Post
template_name = "public/search.html"
paginate_by = 3
HTML:
{% extends 'public/base.html' %}
{% load staticfiles %}
{% block head %}
<link rel="stylesheet" type="text/css" href="{% static "public/css/search.css" %}" />
{% endblock %}
{% block content%}
<div class="search container-fluid">
<img src="/media/about-us.jpg" alt="">
<div class="search-title">
<h1 class="title">Search</h1>
</div>
<div class="search-main mb-5">
<form method='GET' action=''>
<input type="text" name='q' class="homebanner-search" placeholder="Enter your keywords" value='{{ request.get.q }}'>
</form>
</div>
</div>
<div class="container mt-5 mb-5">
<div class="detail-container">
{% for post in queryset %}
<a href="{% url 'post-detail' post.slug %}">
<div class="post-main">
<div class="post-image">
<img src="{{ post.image.url }}" class="card-img-top" alt="#">
<p class="post-category">{{ post.category }}</p>
</div>
<div class="post-body">
<div class="post-title">
<p class="post-title-p">Day in the life of {{ post.title }}</p>
</div>
<div class="post-text">
<p class="post-author-text text-muted">{{ post.sub_description|truncatewords:22 }}</p>
</div>
<div class="post-button">
<p>READ MORE ></p>
</div>
</div>
</div>
</a>
{% endfor %}
</div>
<div id="page_navigation" >
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
So on the page, 3 items should be showing, and pagination should take me to the the next set of 3. The html is showing, and when I click the links it is taking me 2 page 2. The problem is the fact that 6 items are showing, and not 3, and when I go to page 2, there are the same 6 items there.
Unfortunately I couldn't reproduce your error exactly, but what did happen is that my objects wouldn't render when looping through queryset. So what I would recommend is try to loop through object_list instead:
{% for post in object_list %}
{{ post.name }}
{% endfor %}
Another thing you can do is add a context_object_name argument to your view:
class SearchListView(ListView):
model = Post
template_name = "public/search.html"
paginate_by = 3
context_object_name = 'posts'
and then loop through that:
{% for post in posts %}
{{ post.name }}
{% endfor %}
Also, I can't visualise what the search form is doing on this page since the ListView's model (Post) is the queryset, not whatever is searched for? So perhaps the link href is causing some trouble. Maybe try something like this instead:
<li>«</li>
Again, I could not reproduce the exact problem you are having, which is a shame because I feel like I have had the same issue before, so these are just suggestions pieced together from pagination that works for me and the code you posted. Hope it points you in the right direction.

How to correct logic in comments View?

I build comments functional for post but has bug. When someone comment post, another user see correct comment body, but incorrect image and
def p(request, pk):
user = request.user
#user_that_text_comment = User.objects.filter(pk=pk)
topic = get_object_or_404(Topic, pk=pk)
post = get_object_or_404(Post, pk=pk)
comment = Comments.objects.filter(pk=pk)
if request.method == 'POST':
form = CustomCommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.creator = user
comment.save()
comment = Comments.objects.create(
body=form.cleaned_data.get('body'),
creator=user,
)
return render(request, 'post.html', {'post': post, 'topic': topic, 'comment': comment, 'form': form})
else:
form = CustomCommentForm()
return render(request, 'post.html', {'post': post, 'topic': topic, 'comment': comment, 'form': form})
I builded comment function for post but it has bug. When someone comment post, another user see correct comment body, but incorrect image and name.
i know why i has this problem(i suppose), it happend because i use user=request.user. Notice on string that i comment on 3 line. I was think that will help me,but it isn't. I use primary key in my url. url(r'^boards/(?P<pk>\d+)/$', views.board_topics, name='board_topics'), and when i use primary key in filter it return to me user that has same pk as post pk. I need that it return to me username and picture of user that create this comment.
Html template:
<div class="detailBox">
<div class="titleBox">
<label>{{topic.subject}}</label>
<!--<button type="button" class="close" aria-hidden="true">×</button>-->
</div>
<div class="commentBox">
<img src="{{ MEDIA_URL }}{{ topic.image.url }}" alt="">
<p class="taskDescription">{{ post.message|safe|linebreaks}}</p>
</div>
<div class="actionBox">
<ul class="commentList">
{% for comment in post.comment.all %}
<li>
<div class="commenterImage">
{% if user.profile.profile_img %}
<img src="{{ MEDIA_URL }}{{ user.profile.profile_img.url }}" >
{{ user.username }}
{% else %}
<img src="https://image.freepik.com/free-vector/no-translate-detected_1053-593.jpg">
{{ user.username }}
{% endif %}
</div>
<div class="commentText">
<p class="">{{ comment.body }}</p> <span class="date sub-text">{{comment.created_at}}</span>
</div>
</li>
{% endfor %}
</ul>
<form class="form-inline" role="form" method="post">
{% csrf_token%}
{{form}}
<button type="submit" class="btn btn-default">Add</button>
</form>
</div>
</div>{% endblock %}
You should add the comment prefix and relate to the creator to the variables inside the comment
<li>
<div class="commenterImage">
{% if comment.creator.profile.profile_img %}
<!-- ^^^^^ -->
<img src="{{ MEDIA_URL }}{{ comment.creator.profile.profile_img.url }}" >
<!-- ^^^^^ -->
{{ comment.creator.username }}
<!-- ^^^^^ -->
{% else %}
<img src="https://image.freepik.com/free-vector/no-translate-detected_1053-593.jpg">
{{ user.username }}
{% endif %}
</div>
<div class="commentText">
<p class="">{{ comment.body }}</p> <span class="date sub-text">{{comment.created_at}}</span>
</div>
</li>

Categories