How do I affect a single looped element in Django html? - django

I'm building an app in Django, using Bulma for styling. I have a Polishes model that has a favorites field, which references the User (users can save polishes to their list of favorites):
models.py:
class Polish(models.Model):
name = models.CharField(max_length=100)
image = models.CharField(max_length=400, default="https://www.dictionary.com/e/wp-content/uploads/2018/02/nail-polish-light-skin-tone.png")
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='polishes')
favorites = models.ManyToManyField(User, related_name='favorite', default=None, blank=True)
def __str__(self):
return self.name
The add_favorites function checks to see if the polish has been added to the user's favorites already, and if it has, it removes the polish from the list. If it hasn't, it adds it:
views.py:
# login_required
def add_favorite(request, id):
polish = get_object_or_404(Polish, id=id)
if polish.favorites.filter(id=request.user.id).exists():
polish.favorites.remove(request.user.pk)
else:
polish.favorites.add(request.user.pk)
return redirect('favorites_list')
When I render the list of polishes, I'm using Bulma cards, displaying one polish per card. In the footer of the card, I want it to say 'Save to Favorites' if the polish is not in the user's list of favoties and 'Remove from Favorites' if it is. I'm struggling to get this piece to work. It will currently show either Save to Favorites or Remove from Favorites on all of the cards.
Does anyone have any insight on how to render a different message only on those that are already on the favorites list?
polish_list.html:
...
<div class="gallery">
{% for polish in polishes %}
<a href="{% url 'polish_reviews' polish.pk %}">
<div class="card">
<div class="card-header">
<p class="card-header-title">{{polish.name}} by {{polish.brand}}</p>
</div>
<div class="card-image">
<figure class="image is-square">
<img src="{{polish.image}}" alt="{{polish.name}}" />
</figure>
</div>
<footer class="card-footer">
{% if polish.favorites %}
Remove from Favorites
{% elif user.is_authenticated %}
Save to Favorites
{% else %}
Save to Favorites
{%endif%}
</footer>
</div>
</a>
{% empty %}
<article class="message">
<div class="message-header">
<p>No Polishes Available</p>
</div>
</article>
{% endfor %}
</div>
...
I have tried using a conditional in my polish_list.html - {% if polish.favorites %} - but this will make the change on all of the cards rather than just on those that are saved to favorites.

Related

Have issues getting data to display on my web application

I am trying to get the "About us" information from my database to my web application but its not displaying, what could be wrong...
here is the code from the database
class About(models.Model):
about_us = models.TextField()
achieve = models.TextField(blank=True)
image_abt = models.ImageField(upload_to="admin_pics", null=True)
class Meta:
verbose_name_plural = "About Us"
def __str__(self):
return self.about_us
and here is the Html code `
{% extends 'jtalks/base.html' %}
{% load static %}
{%block content%}
<section id="about-home">
<h2>About Us</h2>
</section>
<section id="about-container">
{% for about in abouts %}
<div class="about-img">
<img src="{{ about.image_abt.url }}" alt="">
</div>
<div class="about-text">
<h2>Welcome to TechEduca, Enhance your skills with best Online Courses</h2>
<p>{ about.about_us}</p>
<div class="about-fe">
<img src="images/fe1.png" alt="">
<div class="fe-text">
<h5>400+ Courses</h5>
<p>You can start and finish one of these popular courses in under our site</p>
</div>
</div>
<div class="about-fe">
<img src="images/fe2.png" alt="">
<div class="fe-text">
<h5>Lifetime Access</h5>
<p>You can start and finish one of these popular courses in under our site</p>
</div>
</div>
</div>
{% endfor %}
</section>
{% endblock %}
Nothing is displaying in the frontend of the website.
Thanks for sharing the view. You forgot to pass data to your template. To do that you have to create the queryset and pass that into a dictionary like below. Add the context variable to your render method so you can access the data in the template.
def about(request):
about = About.objects.all()
context = {
'abouts': about,
}
return render(request, 'jtalks/about.html', context)
also, in your html code i see { about.about_us}, but you have to use double curly brackets: {{ about.about_us }}

How can I iterate over a list of a user's followers and each of the follower's followers in a template?

I am asking this question again because I did not receive a satisfactory answer in my previous attempt. It may be difficult for me to fully convey the issue I am trying to resolve, but I will do my best to provide a clear and concise explanation.
.
I am trying to run a query that retrieves a list of followers, as well as the list of followers and followings for each follower. I have included an image that illustrates this structure. I am currently using the following code to attempt this, but it is not producing the expected results. Can you help me understand what I am doing wrong and how I can correctly run this query?
views.py
def get_context_data(self, *args, **kwargs):
context = super(FollowerView,self).get_context_data(*args, **kwargs)
user = context['user']
user_com = User.objects.get(username=user)
myfollowers = user_com.is_following.all()
followers_Array =[]
followerings_Array =[]
for target_list in myfollowers:
user_obj = User.objects.get(username=target_list)
followers_obj = user_obj.is_following.all()
print(followers_obj,'name o ki line')
followerings_Array.append(followerings_Array)
print(followers_obj,user_obj)
followerings_obj = user_obj.userprofile.follower.all()
followerings_Array.append(followerings_obj)
print(followerings_obj,user_obj)
print(followerings_Array,'arry one one one ')
context['myfollowers_data']= followers_Array
context['myfollowerings_data']= followerings_Array
return context
I am currently using two arrays in my code, but I would prefer to avoid doing so if possible. My current implementation is not producing the desired output when I return the arrays in the context. Can you suggest an alternative approach that allows me to display the data in the manner illustrated in the image, and can you review the followers template to see if I am making any mistakes there?
{% for follower in user.is_following.all %}
<div class="followers-body">
<img class="img-responsive img-circle" src="{{follower.avatar.url}}" alt="">
<div class="name-box">
<h4>{{follower}}</h4>
<span>#{{follower}}</span>
<div class="followers-base">
<ul class="list-group">
<li class="list-group-item full-width">
<div class="pull-left" style="margin-right: 20px;">
{% if myfollowers_data %}
{% for user in myfollowers_data %}
<img src="{{user.userprofile.avatar.url}}" alt="" class="img-circle max-w-40 ">
{% endfor %}
{% endif %}
<span> {{myfollowers_data.count}} Followers </span>
</div><!--/ pull-left -->
</li>
<li class="list-group-item full-width">
<div class="pull-left">
{% for usr in myfollowerings_data %}
<img src="{{usr.userprofile.avatar.url}}" alt="" class="img-circle max-w-40 ">
{% endfor %}
<span> {{myfollowerings_data|length}} Following </span>
</div><!--/ pull-right -->
</li><!--/ list-group-item -->
</ul>
</div><!--/ followers-base -->
</div><!--/ name-box -->
<span> Follow</span>
</div><!--/ followers-body -->
{% endfor %}
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
follower = models.ManyToManyField(User, related_name ='is_following',blank=True,)
close_friends = models.ManyToManyField(User,related_name='my_close_friends', blank=True)
rank = models.ManyToManyField(Rank, related_name='rank', default='Newbie', blank=True)
avatar = models.ImageField(("Avatar"), upload_to='displays', default = '1.jpg',height_field=None, width_field=None, max_length=None,blank = True)
create_date = models.DateField(auto_now_add=True,null=True)
#property
def email_address(self):
return self.user.email
objects = ProfileManager()
def __str__(self):
return f'{self.user.username}'
def get_absolute_url(self):
return reverse("profiles:final_detail", kwargs={"username": self.user.username})
If more code in require than tell me in a comment session. I will update my question with that information.
Okay, this should all be achievable from the template:
template.html:
<!-- users followers -->
{% for follower1 in user.is_following.all %}
<img src="{{ follower1.avatar.url }}"/>
<!-- followers followers -->
{% for follower2 in follower1.is_following.all %}
<img src="{{ follower2.avatar.url }}"/>
...
{% endfor %}
{% endfor %}

how can i use two types of queryset models override save method?

i want to ask you if i POST an article with featured=True then the old featured=true get transferred to featured=false queryset. i just want two [:2] values in featured=true queryset. here is the example of what i want
there are two article in featured=true queryset which i want the second article automatically get updated to featured=false when i create new article.
the output of my code when i applied is featuring only one article. were as i want two articles to be featured.
Here is the query of database with print(featured_articles.count()), photo of the list of articles in the admin, and the template.
models.py
class ArticleQuerySet(models.Manager):
def get_queryset(self):
return super(ArticleQuerySet,self).get_queryset().filter(status=True)
class Article(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True)
thumbnail = models.ImageField(default='def.jpg',
upload_to='article/thumbnails')
timestamp = models.DateTimeField(auto_now_add=True)
content = RichTextUploadingField(blank=True)
featured = models.BooleanField(default=False)
status = models.BooleanField(default=True)
tags = TaggableManager()
objects = models.Manager()
status_objects = ArticleQuerySet()
def __str__(self):
return self.title
class Meta:
ordering = ['-timestamp']
# i also try this method
def save(self, *args, **kwargs):
if self.featured == True:
Article.objects.filter(pk__in=(Article.objects.filter(featured=True,
).values_list('pk',flat=True)[:2])).update(featured=False)
self.featured = True
super(Article, self).save(*args, **kwargs)
views.py
from django.shortcuts import render
from .models import Article
def index(request):
featured_articles = Article.status_objects.filter(tags__exact='1', featured=True)[:2]
regular_articles = Article.status_objects.filter(tags__exact='1').exclude(pk__in=featured_articles)
context = {
'featured': featured_articles,
'regular': regular_articles,
}
return render(request, 'news/index.html', context)
index.html
<!--post header-->
<div class="post-head">
<h2 class="title"> Article </h2>
</div>
<!-- post body -->
<div class="post-body">
<div class="">
<!-- item one -->
<div class="item">
<div class="row">
<div class="col-sm-6 main-post-inner bord-right">
{% for nat in featured %}
<article>
<figure>
<a href="{% url 'news-detail' pk=nat.pk %}"><img src="{{ nat.thumbnail.url }}"
height="242" width="345" alt="" class="img-responsive"></a>
</figure>
<div class="post-info">
<h3>{{ nat.title }}
</h3>
<span>
<i class="ti-timer"></i>
{{ nat.timestamp | timesince }}
</span>
<p></p>
</div>
</article>
{% endfor %}
</div>
<div class="col-sm-6">
<div class="news-list">
{% for nat in regular %}
<div class="news-list-item">
<div class="img-wrapper">
<a href="{% url 'news-detail' pk=nat.pk %}" class="thumb">
<img src="{{ nat.thumbnail.url }}" alt="" class="img-responsive">
<div class="link-icon">
<i class="fa fa-camera"></i>
</div>
</a>
</div>
<div class="post-info-2">
<h5>{{ nat.title }}
</h5>
<i class="ti-timer"></i> {{ nat.timestamp | timesince }}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Your code looks fine, but the standard way of doing this is keeping all marked as featured as is, without marking previous featured articles as featured=False:
views.py
def articles(self):
featured_articles = Article.status_objects.filter(tags__exact='1', featured=True)[:2]
regular_articles = Article.status_objects.filter(tags__exact='1').exclude(pk__in=featured_articles)
...
Note how .exclude(featured=True) is not in the regular_articles queryset. Old featured articles will automatically rollover into this queryset.
Some advantages of this approach are:
No need to maintain the list of featured articles
You get to keep a list of previously featured articles
You don't run into race conditions when multiple articles are being added/featured
You don't bother the database with updates
Your code is easier to maintain and read
Updating a single article doesn't have side effects (e.g. when you update an article, you know for sure you are only updating that article, nothing else)
That being said, there are times when you actually want to mark them as featured=false, but unless you have a compelling reason to, it's usually better to keep things simpler.
There is more better way for this. Create One new model like this.
remove featured field from your article model.
class featured (models.Model):
featured=models.OneToOneField(Article, related_name='featured', on_delete=models.CASCADE )
create as much featured article you want to featured.
suppose you want only two featured article, then create only two record.
whenever you want to change your featured article just update that record.
i hope this will be simple design and very flexible also you can increase featured article as much as you want by just adding new record and decrease as much as you want by just delete.
here you don't want to override your article save method.

IF conditional statement in Django template does not work

{% if user.resume %}
<div class="empty-state-box">
<img src="{% static 'resumes/images/resume-empty-icon.png' %}" class="centered">
<p class="empty-state-text"><b>You currently don't have any resumes.</b><br>Create one and
start building your very first resume</p>
</div>
{% else %}
<p>More information here</p>
{% endif %}
models.py
from django.db import models
from users.models import User
class Resume(models.Model):
name = models.CharField(max_length=255, blank=True)
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
#login_required()
def my_resumes(request):
return render(request, 'resumes/myresumes.html')
I'm trying to place an empty state if a user does not have a resume. Else, I want to show other information. I can't seem to get it to work. I think I am using the if conditional statement wrong in the template.
First, your condition seems turned the wrong way. You code handling the case when the resume is not present is in the if user.resume statement. So it should rather be if not user.resume.
Second, the reverse relation is not named user.resume but user.resume_set. You can change this name using related_name if you want. For instance: user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='resumes') would enable to access it via user.resumes instead of user.resume_set.
Yet, if user.resume_set will always be evaluated to if True because it is a related manager, not a queryset. So you could do something like this:
{% if not user.resume_set.exists %}
<div class="empty-state-box">
<img src="{% static 'resumes/images/resume-empty-icon.png' %}" class="centered">
<p class="empty-state-text"><b>You currently don't have any resumes.</b><br>Create one and
start building your very first resume</p>
</div>
{% else %}
<p>More information here</p>
{% endif %}
However, in your else statement, you will likely iterate over resumes with something like this {% for resume in user.resume_set.all %}. In such, case you will hit twice the database. Once for user.resume_set.exists and once for user.resume_set.all, which is not needed because you can know the result of user.resume_set.exists from the result of user.resume_set.all. Django templates allows you to do something like this to handle empty case when iterating an object:
{% for resume in user.resume_set.all %}
Your code to display a resume item here
{% empty %}
<div class="empty-state-box">
<img src="{% static 'resumes/images/resume-empty-icon.png' %}" class="centered">
<p class="empty-state-text"><b>You currently don't have any resumes.</b><br>Create one and
start building your very first resume</p>
</div>
{% endif %}
But still, it is not very good practice to execute querysets in a template. To avoid this, you can pass it in your view:
#login_required()
def my_resumes(request):
context = {'resumes': request.user.resume_set.all()}
return render(request, 'resumes/myresumes.html', context)
Now you can do:
{% for resume in resumes %}
Your code to display a resume item here
{% empty %}
<div class="empty-state-box">
<img src="{% static 'resumes/images/resume-empty-icon.png' %}" class="centered">
<p class="empty-state-text"><b>You currently don't have any resumes.</b><br>Create one and
start building your very first resume</p>
</div>
{% endif %}
Note that you can also use the previous syntax, it will only hit the database once:
{% if not resumes %}
<div class="empty-state-box">
<img src="{% static 'resumes/images/resume-empty-icon.png' %}" class="centered">
<p class="empty-state-text"><b>You currently don't have any resumes.</b><br>Create one and
start building your very first resume</p>
</div>
{% else %}
<p>More information here</p>
{% for resume in resumes %}
Your code to display a resume item
{% endfor %}
{% endif %}
You need to rename the backwards relationship on your resume class so you can access it using {{ user.resume }}.
By default the ForeignKey relationship you've defined from the resume to the user is accessible using user.resume_set. See the docs for more detail.
I'm guessing that you only want to have a single resume per user, so you'll probably want to use a OneToOneField instead of a ForeignKey.
class Resume(models.Model):
name = models.CharField(max_length=255, blank=True)
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="resume")
def __str__(self):
return self.name
Additionally, your if appears to be round the wrong way, given you probably want the form to appear when a resume doesn't exist.
{% if user.resume.exists %}
<p>More information here</p>
{% else %}
<div class="empty-state-box">
<img src="{% static 'resumes/images/resume-empty-icon.png' %}" class="centered">
<p class="empty-state-text"><b>You currently don't have any resumes.</b><br>Create one and
start building your very first resume</p>
</div>
{% endif %}

Menu with permissions in django

I am creating a modular menu in Django that has the following structure;
class Pagina(models.Model):
nome = models.CharField(max_length=250, blank=True)
url = models.CharField(max_length=250)
def __str__(self):
return self.nome
class Voce(models.Model):
nome = models.CharField(max_length=250, blank=True)
Pagine = models.ManyToManyField(Pagina)
Permesso = models.ForeignKey(Permesso, on_delete=models.CASCADE)
def __str__(self):
return self.nome
class Menu(models.Model):
Voci = models.ManyToManyField(Voce)
I need to check if the user has the required permission to see the submenu(permission that is in a group).
The menu is rendered the following way;
{% for voce in menu.Voci.all %}
<li class="m-menu__item m-menu__item--submenu m-menu__item--rel {% ifequal parent voce.nome %}m-menu__item--active{% endifequal %}" m-menu-submenu-toggle="click" aria-haspopup="true">
<a href="javascript:;" class="m-menu__link m-menu__toggle">
<span class="m-menu__item-here"></span><span class="m-menu__link-text">{{voce}}</span><i class="m-menu__hor-arrow la la-angle-down"></i><i class="m-menu__ver-arrow la la-angle-right"></i>
</a>
<div class="m-menu__submenu m-menu__submenu--classic m-menu__submenu--left"><span class="m-menu__arrow m-menu__arrow--adjust"></span>
<ul class="m-menu__subnav">
{% for pagina in voce.Pagine.all %}
<li class="m-menu__item {% ifequal request.path pagina.url %}m-menu__item--active{% endifequal %}" aria-haspopup="true">
<a href="{{pagina.url}}" class="m-menu__link ">
<i class="m-menu__link-bullet m-menu__link-bullet--line"><span></span></i>
<span class="m-menu__link-title"><span class="m-menu__link-wrap"><span class="m-menu__link-text">{{pagina.nome}}</span></span></span>
</a>
</li>
{% endfor %}
</ul>
</div>
</li>
{% endfor %}
The check would need to happen just after the first for loop starts in order to determine whether or not to display that particular submenu.
The "gruppo" object of the user is a foreignkey relation to a personalized Group object, which has a ManyToMany relation with different permissions, each having a name. I need to check if a user has the same permission as the "Voce" model currently being looped through.
Thank you for your time,
Matteo