In django, getting the following usernames in user profile - django

i'm building a following model. I have created a following model as shown below and it is working fine in the admin. I did not create a view for the following because i'm in primary stage of building i'm testing in templates to bring that usernames in userspostlist, but it's not working.
my models.py for following:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='owner', on_delete=models.CASCADE)
following = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='followed_by')
def __str__(self):
return str(self.following.all().count())
class post(models.Model):
parent = models.ForeignKey("self", on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='post_pics', null=True, blank=True)
video = models.FileField(upload_to='post_videos', null=True, blank=True)
content = models.TextField()
likes = models.ManyToManyField(User, related_name='likes', blank=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
objects = postManager()
def __str__(self):
return self.title
my views.py for userpostlist:
class UserPostListView(ListView):
model = post
template_name = 'blog/user_post.html' #<app>/<model>_<viewtype>.html
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return post.objects.filter(author=user).order_by('-date_posted')
and my userpostlist.html:
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h1 class="mb-3">posts by {{view.kwargs.username}}</h1>
{% for user in username.owner.following.all %}
{{ user.username }}
{% endfor %}
{% for post in posts %}
<article class="content-section">
<div class="article-metadata">
<div class="img">
<img class="rounded-circle article-img" data-toggle="modal" data-target="#mymodal" src="{{ post.author.profile.image.url }}">
</div>
<div class="profile-info">
<a class="h2" href="{% url 'user-posts' post.author.username %}">{{ post.author }}</a>
<div class="text-muted">{{ post.date_posted }}</div>
</div>
</div>
{% endfor %}
{% endblock content %}
Is there any problem with the userpostlist view in views.py? do i need to add some code there?

You have some options here, where one is to pass users into context:
class UserPostListView(ListView):
...
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['author'] = get_object_or_404(User, username=self.kwargs.get('username')
return context
And then instead of this:
{% for user in username.owner.following.all %}
{{ user.username }}
{% endfor %}
Use this:
{{ author.username }}

Related

Django - Giving a view access to multiple models

I followed a tutorial on Youtube that makes a website to create posts. Currently, I am working on displaying other people's profiles and their posts on their profile pages. I did it by accessing the author of the first post, but it only works if the user posted something. Is there another way to do it?
The view:
class UserProfileView(ListView):
model = Post
template_name = 'blog/user_profile.html' # defaults to <app>/<model>_<viewtype>.html--> blog/post_list.html
context_object_name = 'posts' #defaults to objectlist
paginate_by = 5
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
user_profile.html:
{% extends 'blog/base.html' %}
{% block title %}{{ view.kwargs.username }}'s Profile{% endblock title %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ posts.first.author.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ view.kwargs.username }}</h2>
<p class="text-secondary">{{ posts.first.author.email }}</p>
<p class="article-content">{{ posts.first.author.profile.bio }}</p>
</div>
</div>
{% if posts.first.author == user %}
<a class="btn btn-outline-secondary ml-2" href="{% url 'change_profile' %}">Edit Profile</a>
{% endif %}
</div>
<br>
{% if posts.first.author == user %}
<h3 class="ml-2 article-title">Blogs You Posted</h3>
{% else %}
<h3 class="ml-2 article-title">Blogs By {{ view.kwargs.username }}</h3>
{% endif %}
And the Post and Profile module:
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk':self.pk})
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=225, blank=True, default='')
def __str__(self) -> str:
return f"{self.user.username}'s Profile"
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
img.thumbnail((300,300))
img.save(self.image.path)
First off, you probably don't need .first in your template, because you are using the first item from the QuerySet. If you are accessing a User profile, you can use the DetailView. In addition, you can try from a different page and provide filtered posts in context. Something like this, for example.
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['posts'] = Post.objects.filter(author=user) # from kwargs
return context
#template
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
<li>{{ post.content }}</li>
<li>{{ post.date_posted }}</li>
{% endfor %}
</ul>
PS Regards to Corey.

Django Views has an issue not allowing all Context Variables to appear in template

I have made a Slider Model which contains 3 images and Texts related to it to slide in a Carousel
My issue is that I want these images to be shown as per the order assigned as per the model but only one appears.
If I remove the {% if sliders %} {% for slider in sliders %} the latest image only appears because in the views it is filtered by .latest('timestamp')
I have also tried to replace .latest('timestamp') in the views with .all() it still didn't work
This is the model:
class Slider(models.Model):
title = models.CharField(max_length=60)
image = models.ImageField(blank=False, upload_to='Marketing')
order = models.IntegerField(default=0)
header_text = models.CharField(max_length=120, null=True, blank=True)
middle_text = models.CharField(max_length=120, null=True, blank=True)
footer_text = models.CharField(max_length=120, null=True, blank=True)
button_text = models.CharField(max_length=120, null=True, blank=True)
active = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
class Meta:
ordering = ['order']
def __str__(self):
return self.title
def get_image_url(self):
return "%s/%s" % (settings.MEDIA_URL, self.image)
This is the view:
class HomeView(ListView):
model = Item
paginate_by = 10
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super(HomeView, self).get_context_data(**kwargs)
try:
context['marketing_message'] = MarketingMessage.objects.filter(
active=True).latest('timestamp')
except MarketingMessage.DoesNotExist:
context['marketing_message'] = None
try:
context['slider'] = Slider.objects.filter(
active=True).latest('timestamp')
except Slider.DoesNotExist:
context['slider'] = None
return context
This is the template:
{% if slider %}
{% for slider in sliders %}
<div class="carousel-item {% if forloop.first %} active {% endif %}">
<div class="view" style="background-image: url('{{ slider.get_image_url }}'); background-repeat: no-repeat; background-size: cover;">
<div class="mask rgba-black-strong d-flex justify-content-center align-items-center">
<div class="text-center white-text mx-5 wow fadeIn">
<h1 class="mb-4">
{% if slider.header_text %}
<strong>{{ slider.header_text }}</strong>
{% endif %}
</h1>
<p>
{% if slider.middle_text %}
<strong>{{ slider.middle_text }}</strong>
{% endif %}
</p>
<p class="mb-4 d-none d-md-block">
{% if slider.footer_text %}
<strong>{{ slider.footer_text }}
</strong>
{% endif %}
</p>
{% if slider.button_text %}
<a target="_blank" href="" class="btn btn-outline-white btn-lg">
{{ slider.button_text }}
<i class="fas fa-graduation-cap ml-2"></i>
</a>
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
make following changes
views.py
class HomeView(ListView):
model = Item
paginate_by = 10
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super(HomeView, self).get_context_data(**kwargs)
try:
context['marketing_message'] = MarketingMessage.objects.filter(active=True).latest('timestamp')
except MarketingMessage.DoesNotExist:
context['marketing_message'] = None
try:
context['sliders'] = Slider.objects.filter(active=True).order_by('timestamp')
except Slider.DoesNotExist:
context['sliders'] = None
return context
template
{% if sliders %}
{% for slider in sliders %}
#Your html code
{% endfor %}
{% endif %}
You have declared context['slider'] in views.py whereas, you call it sliders in your templates.
Now you will not be able to loop through because that calls one object only so do the following changes in views.py:
context['slider'] = Slider.objects.filter(active=True).latest('timestamp')
to
context['slider'] = Slider.objects.filter(active=True)

How to Display subcategory under Category in Django?

I have some issue with displaying WebSubCategory under WebCategory in Django. I have already displayed WebCategory but I am unable to display WebSubCategory under WebCategory.
Here is my models.py file:
class WebCategory(models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name='Category name')
slug = models.SlugField(verbose_name='Slug')
title = models.CharField(max_length=165, null=True)
metadesc = models.TextField(max_length=165, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = 'WebCategory'
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(WebCategory, self).save(*args, **kwargs)
def __str__(self):
return self.name
class WebSubCategory(models.Model):
category = models.ForeignKey('WebCategory', related_name='subcategory', on_delete=models.CASCADE, blank=True,
null=True, verbose_name='Select category')
name = models.CharField(max_length=50)
slug = models.SlugField(unique=True, null=True)
title = models.CharField(max_length=100, null=True)
metadesc = models.TextField(max_length=165, null=True)
description = RichTextField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = 'WebSubCategory'
def __str__(self):
return self.name
Here is my views.py file
def home(request):
context = RequestContext(request)
category_list = WebCategory.objects.order_by('-created_at')[:5]
subcategory_list = WebSubCategory.objects.order_by('-created_at')[:5]
context_dict = {'webcat': category_list, 'websubcat':category_list}
return render_to_response('home.html', context_dict, context)
And here is my header.html file, where i want to diplay category and subcategory
<ul class="nav nav-pills" id="mainNav">
{%if webcat %}
{% for category in webcat %}
<li class="dropdown dropdown-mega">
<a class="dropdown-item dropdown-toggle" href="JavaScript:void()">
{{category.name}}
</a>
{% if websubcat.webcat %}
<ul class="dropdown-menu">
<li>
<div class="dropdown-mega-content">
<div class="row">
{% for subcategory in websubcat.webcat %}
<div class="col-lg-3">
<span class="dropdown-mega-sub-title">Elements 1</span>
<ul class="dropdown-mega-sub-nav">
<li><a class="dropdown-item" href="elements-accordions.html">{{subcategory.name}}</a></li>
</ul>
</div>
{% endfor %}
</div>
</div>
</li>
</ul>
{% else %}
<p>Not Found Submenu</p>
{% endif %}
</li>
{% endfor %}
{% else %}
<p>No Category Found</p>
{% endif %}
Blog
Please help me to display the WebSubCategory under WebCategory.
{% if webcat_set.all|length > 0 %}
{% for subcategory in webcat_set.all %}
<div class="col-lg-3">
<span class="dropdown-mega-sub-title">Elements 1</span>
<ul class="dropdown-mega-sub-nav">
<li><a class="dropdown-item" href="elements-accordions.html"> {{subcategory.name}}</a></li>
</ul>
</div>
{% endfor %}
{% endif %}

how to iterate on two subclass models with same for loop?

I want to create a photo sharing website, but i don't know how to iterate over
this code:
all_post = Images.objects.all().order_by('-created').select_subclasses()
my models.py
class Images(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='images_created', on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
objects = InheritanceManager()
class Postimg(Images):
user_img= models.ImageField(upload_to='images/%Y/%m/%d', null=True, blank=True)
class Postsms(Images):
user_message = models.CharField(max_length=500,blank=True)
views.py
#login_required
def home(request):
all_post = Images.objects.all().order_by('-created').select_subclasses()
return render(request, 'copybook/home.html',{ 'all_post':all_post})
home.html
{% for foo in all_post %}
<hr>
<br> SMS by: <p>{{ foo.user}} __ {{ foo.created }}</p> <br>
<h2>{{ foo.user_message }}</h2>
<hr>
<br> IMAGE by: <p>{{ foo.user}} __ {{ foo.created }}</p> <br>
<img src="{{ foo.user_img.url }}"width="250">
{% endfor %}
how do i iterate it in home.html

Django unrecognized token: "#" while query

I simply want to implement a search view into my Django app. But when i try to search something on my App i get the following error:
'unrecognized token: "#"'
In the end i want that my Query is a combination of category and searchword. So that the user can filter specific categories (Just like Amazon.com searchfield) e.g.: http://127.0.0.1:8000/search/?category=1&q=hallo
base.html
...
<div class="globalsearch">
<form id="searchform" action="{% url 'search' %}" method="get" accept-charset="utf-8">
<label for="{{ categorysearch_form.category.id_for_label }}">In category: </label> {{ categorysearch_form.category }}
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search for ...">
<button class="searchbutton" type="submit">
<i class="fa fa-search"></i>
</button>
</form>
</div>
</div>
...
categorysearch_form is a dropdown selector that gets his ID from the Database.
views.py
...
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
from django.views.generic import ListView
class globalsearch(ListView):
"""
Display a Post List page filtered by the search query.
"""
model = Post
paginate_by = 10
def get_queryset(self):
qs = Post.objects.all()
keywords = self.request.GET.get('q')
if keywords:
query = SearchQuery(keywords)
title_vector = SearchVector('title', weight='A')
content_vector = SearchVector('content', weight='B')
tag_vector = SearchVector('tag', weight='C')
vectors = title_vector + content_vector + tag_vector
qs = qs.annotate(search=vectors).filter(search=query)
qs = qs.annotate(rank=SearchRank(vectors, query)).order_by('-rank')
return qs
...
urls.py
...
url(r'^search/$', views.globalsearch.as_view(), name='search'),
...
Search.html results are getting displayd here:
{% extends 'quickblog/base.html' %}
{% block content %}
{% for post in object_list %}
<div class="post">
<h1><u>{{ post.title }}</u></h1>
<p>{{ post.content|linebreaksbr }}</p>
<div class="date">
<a>Published by: {{ post.author }}</a><br>
<a>Published at: {{ post.published_date }}</a><br>
<a>Category: {{ post.category }}</a><br>
<a>Tag(s): {{ post.tag }}</a>
</div>
</div>
{% endfor %}
Post Model
...
#Post Model
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=75)
content = models.TextField(max_length=10000)
tag = models.CharField(max_length=50, blank=True)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
postattachment = fields.FileField(upload_to='postattachment/%Y/%m/%d/', blank=True ,null=True)
postcover = fields.ImageField(upload_to='postcover/%Y/%m/%d/', null=True, dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 200, 'max_height': 200}))
])
created_date = models.DateField(auto_now_add=True)
published_date = models.DateField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
class Meta:
ordering = ["-title"]
def __str__(self):
return self.title
...
i guess im simply missing something
at that point...
I already read that this issue comes from local SQL database aka. SQLite, could that be true?
Smb. has a solution?
Thanks
After a bit of tinkering with a friend i found a solution, the Django Documentation according to vector searching is really not that good...
views.py
class globalsearch(ListView):
"""
Display a Post List page filtered by the search query.
"""
model = Post
paginate_by = 10
template_name = 'quickblog/search.html'
def get_queryset(self):
keywords = self.request.GET.get('q')
if keywords:
query = SearchQuery(keywords)
title_vector = SearchVector('title', weight='A')
content_vector = SearchVector('content', weight='B')
tag_vector = SearchVector('tag', weight='C')
vectors = title_vector + content_vector + tag_vector
qs = Post.objects.annotate(rank=SearchRank(vectors, query)).filter(rank__gte=0.1).order_by('-rank')
return qs
models.py
#Post Model
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=75)
content = models.TextField(max_length=10000)
tag = models.CharField(max_length=50, blank=True)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
postattachment = fields.FileField(upload_to='postattachment/%Y/%m/%d/', blank=True ,null=True)
postcover = fields.ImageField(upload_to='postcover/%Y/%m/%d/', null=True, dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 200, 'max_height': 200}))
])
created_date = models.DateField(auto_now_add=True)
published_date = models.DateField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
class Meta:
ordering = ["-title"]
def __str__(self):
return self.title
search.html
{% extends 'quickblog/base.html' %}
{% block content %}
{% for post in object_list %}
<div class="post">
<h1><u>{{ post.title }}</u></h1>
<p>{{ post.content|linebreaksbr }}</p>
<div class="date">
<a>Published by: {{ post.author }}</a><br>
<a>Published at: {{ post.published_date }}</a><br>
<a>Category: {{ post.category }}</a><br>
<a>Tag(s): {{ post.tag }}</a>
</div>
</div>
{% endfor %}
{% 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 %}
{% endblock %}
urls.py
url(r'^search/$', views.globalsearch.as_view(), name='search'),
Hope that i was able to help the next one with that Post :D