Django _set.all in template with one to many relationship - django

I am trying to output a web page with many blog posts, each of them potentially containing many images.
Models.py:
class FreeImage(models.Model):
f_img = models.ImageField(null=True, blank=True, upload_to="img/f")
f_img_alt = models.CharField(max_length=100, blank=True, null=True)
post = models.ForeignKey('Post', on_delete=models.SET_NULL, null=True)
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
Views.py:
def home_view(request):
posts = Post.objects.order_by('-id')
freeimgs = FreeImage.objects.filter(post__in=posts)
context = {
'posts':posts,
'freeimgs' :freeimgs,}
return render(request, 'home.html', context)
Template:
{% extends 'base.html' %}
{% block main %}
{% for post in posts%}
<h3>{{post.title}}</h3>
{% for i in freeimgs.post_set.all %}
<h5>Test</h5>
<img src="{{ freeimage.f_img.url }}" alt="{{freeimage.f_img_alt}}">
{% endfor %}
{% endfor %}
{% endblock %}
freeimgs.post_set.all does not return anything here. I have no idea how else I could show the images corresponding to the right post inside template.

You have reverse accessor from Post to FreeImage and not other way around
{% for free_image in post.freeimage_set.all %}
<h5>Test</h5>
<img src="{{ free_image.f_img.url }}" alt="{{ free_image.f_img_alt}}">
{% endfor %}

Related

How can I grab articles with the same tag, so within a template I can display those articles?

I'm new to Django, so thanks for any help.
I have an Article model, and I would like to display related/similar articles by assigning tags to each article.
I've tried making a function/filter in my views.py that inherits from self (that particular article) and filters out the articles with the same tag, but with no success.
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200, blank=True)
thumbnail = models.ImageField(max_length=200, blank=True)
tag = models.CharField(max_length=200, blank=True)
from .models import Article
class ArticleView(DetailView):
template_name = "article/article.html"
model = Article
def related_articles(self):
tagged = Article.objects.filter(tag=self.tag)
return tagged
{% if articles.objects.all %}
{% for article in article.objects.all|related_articles %}
<div>
<img src="{{ article.thumbnail.url }}">
<span>{{ article.title }}</span>
</div>
{% endfor %}
{% endif %}
So, whenever I try to use this filter I get no results.
I think the related_articles function should be on the model class.
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200, blank=True)
thumbnail = models.ImageField(max_length=200, blank=True)
tag = models.CharField(max_length=200, blank=True)
def related_articles(self):
tagged = Article.objects.filter(tag=self.tag).exclude(pk=self.pk)
Suppose your have a view like this:
def articles(request):
articles = Articles.objects.all()
context = dict(articles=articles)
return render(request, 'app/articles.html', context)
You could have a template like this:
{% if articles|length %}
{% for article in articles %}
<div>
<img src="{{ article.thumbnail.url }}">
<span>{{ article.title }}</span>
{% for related_article in article.related_articles %}
<span>{{ related_article.title }}</span>
{% endfor %}
</div>
{% endfor %}
{% endif %}

Data from Views.Py not showing up on the template

I am trying to find out why some data from my views.py are not showing up. Here's my code
views.py
def user(request, user_id):
profile = get_object_or_404(User, pk=user_id)
rnk = Ranks.objects.all()
context = {
'profile' : profile,
'rnk' : rnk,
}
return render(request, 'user/user.html', context)
I am trying to show, for example the rank_name from my model and I use {{rnk.rank_name}} in the HTML template but it's not showing up.
On the other hand, data from profile like {{profile.user_name}} are showing up.
Note that rnk and profile are from this model:
class Ranks(models.Model):
rank_name = models.CharField(max_length=300)
description = models.TextField(blank=True)
def __str__(self):
return self.br_rank_name
class User(models.Model):
b_rank = models.ForeignKey(Ranks, on_delete=models.DO_NOTHING)
name = models.CharField(max_length=20)
link = models.URLField(max_length=100)
weekly = models.BooleanField(default=False)
biweekly = models.BooleanField(default=False)
def __str__(self):
return self.name
Here's my template
{% extends 'base.html' %}
{% load static %}
{% block content %}
<h5>{{profile.user_name}}</h5><!--This shows up-->
<p>{{rnk.rank_name}}</p>
<p>{{profile.weekly}}</p>
<span class="icon-desc">{{rnk.rank_points}} points</span>
{% endblock %}
That's because the rnk passed to the template is a queryset and includes multiple objects. So you need to iterate rnk using for and try to show the details for each one in your template.
{% extends 'base.html' %}
{% load static %}
{% block content %}
<h5>{{ profile.user_name }}</h5>
<p>{{ profile.weekly }}</p>
{% for rank in rnk %}
<p>{{ rank.rank_name }}</p>
<span class="icon-desc">{{ rank.rank_points }} points</span>
<img src="{{ rank.br_photo.url }}" height="150" alt="">
{% endfor %}
{% endblock %}

Django: output video file associated with a specific user

I have customuser model name Profile and VideoFile models with relative fields to User. There are many users account and each of them can add a lot of video files. I need to show at templates.html user.nickname and all of him videofiles.
user.models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
nickname = models.CharField(max_length=30, blank=True, verbose_name="Никнэйм")
userpic = models.ImageField(upload_to='userpics/', blank=True, null=True)
videofile.models.py
class VideoFile(models.Model):
name = models.CharField(max_length=200,blank=True)
file = models.FileField(upload_to="vstories/%Y/%m/%d", validators=[validate_file_extension])
date_upload = models.DateTimeField(auto_now_add = True, auto_now = False, blank=True, null = True)
descriptions = models.TextField(max_length=200)
reports = models.BooleanField(default=False)
vstories = models.ForeignKey(Profile, blank = True, null = True)
views.py
def vstories (request):
profiles = Profile.objects.all()
return render(request, "vstories/vstories.html", {'profiles':profiles})
templates.html
{% extends "base.html" %}
{% block content %}
{% if users %}
{% for user in users %}
<p>{{ user.profile.nickname}}</p>
{% for vstorie in vstories %}
<p>{{ vstorie.vstories.url }}</p>
{% endfor %}
{% endfor %}
{% endif %}
{% endblock content %}
With the video, I'm confused. Or maybe I chose the wrong way to communicate models?
You can look for the foreign keys "backward". In this case, to access to all videos of a user (Profile), you need to have all Profiles:
def vstories (request):
profiles = Profile.objects.all()
return render(request, "vstories/vstories.html",{'profiles':profiles})
Then, in the template, you can access the relationship between Profile and VideoFile "backward".
{% for profile in profiles %}
{% for videofile in profile.videofile_set.all %}
<p>{{ videofile.file.url }}</p>
{% endfor %}
{% endfor %}
The trick is in the "_set" that allows you to follow the relationship backward.
Here is the documentation for this kind of queryset:
https://docs.djangoproject.com/en/2.0/topics/db/queries/#following-relationships-backward
This work for me
{% for profile in profiles %}
{{ profile.nickname }}
{% for videofile in profile.videofile_set.all %}
<video width="320" height="240" controls src="{{ videofile.file.url }}">
Your browser does not support the video tag.
</video>
{% endfor %}
{% endfor %}

Get Featured Image from different Model

I have 2 model objects, Business & BusinessImage as so, listed with views and index.html. I am trying to list the business's featured image, but it's not happening. I am getting the following error:
'QuerySet' object has no attribute 'businessimage_set'
How can I get the business featured image for a list?
Business
class Business(models.Model):
name = models.CharField("Name", max_length=70, default="Business Name")
slug = models.SlugField()
description = models.TextField("About", max_length=400)
category = models.ManyToManyField(Category, verbose_name="Categories", blank=True)
order = models.IntegerField("Order", default=0)
claimed = models.BooleanField("Claimed", default=False)
featured = models.BooleanField("Featured", default=False)
class Meta:
ordering = ['order']
verbose_name = "Business"
verbose_name_plural = "Businesses"
def __str__(self):
return self.name
BusinessImage
class BusinessImage(models.Model):
business = models.ForeignKey(Business)
image = models.ImageField(upload_to="images/business")
title = models.CharField(max_length=120)
featured = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return self.title
view.py
from .models import Business, BusinessImage
def index_view(request):
latest_business_list = Business.objects.all()
images = latest_business_list.businessimage_set.all()
template = loader.get_template('index.html')
context = RequestContext(request, {
'latest_business_list': latest_business_list,
'images': images,
})
return HttpResponse(template.render(context))
index.html
{% block content %}
<div class="text-center business_title">
<h2>Featured</h2>
</div>
{% if latest_business_list %}
{% for business in latest_business_list|slice:":4" %}
{% if business.active %}
<div class="col-sm-6 col-md-3">
<li>{{ business.name }}</li>
{% for image in latest_business_list.businessimage_set.all %}
{% if image.featured %}
<a href="{% url 'single_product' product.slug %}">
<img src="{{MEDIA_URL}}{{image.image}}" alt="{{image}}">
</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}
businessimage_set is an attribute of a Business instance, but you're trying to access it as an attribute of a queryset (i.e. list of businesses). If your goal is just to be able to access the images for each business in a template, you can leave out images entirely. Instead your template would have:
{% for image in business.businessimage_set.all %}
(Though look into prefetch_related for efficiency.)

Django Duplication objects

I'm trying to implement a comment feature inside my whiteboard.The feature allows Students to comment on each other pictures.
I have an app where students can create virtual whiteboard and post pictures relating to homework inside the whiteboards.
When the user clicks to view the comment under a specific picture . The comment does appear on that specific picture but the same comment appears on all the picture which it isn't suppose too.
I'm been trying figure out a way to implement a comment feature and this is the only idea I though of.
How could I fix this duplication problem because I"m been trying to figure out a way to associate the picture with the comments.
Take a look at the whiteboard >
http://imageshack.us/photo/my-images/836/90792660.jpg/
My whiteboard.html
{% if picture %}
<ul>
{% for pet in picture %}
{% if pet.image %}
<a href ="{% url world:LikePicture pet.id %}"><br>
<img src= "{{ pet.image.url }}" style="cursor:pointer"></a>
<br>
</a>
</li>
{% endif %}
<br>
View Comment<br/>
{% for c in comment %}
<br>{{ c.body }}</li>
<br>{{ c.created}}</li>
<br>{{ c.user}}</li>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
My views.py
def Boat(request ,animal_id):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
picture = Picture.objects.filter(whiteboard=animal_id)
return render(request,'whiteboard.html',{'picture':picture})
def CommentCreator(request,picture_id):
p = Picture.objects.get(pk=picture_id)
comment = Comment.objects.filter(picture=p)
Whiteboard = WhiteBoard.objects.get(whiteboard=p)
the_id = board.id
picture = Picture.objects.filter(whiteboard=the_id)
return render(request,'whiteboard.html',{'picture':picture,'comment':comment})
My models.py
class WhiteBoard(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=100)
picture = models.OneToOneField('Picture',related_name='picture',blank=True,null=True)
def __unicode__(self):
return self.name
class Picture(models.Model):
user = models.ForeignKey(User)
Whiteboard = models.ForeignKey(WhiteBoard,blank=False,null=False,related_name='board')
image = models.FileField(upload_to="images/",blank=True)
description = models.TextField()
is_primary = models.BooleanField(default=False)
def __unicode__(self):
return self.description
class Comment(models.Model):
created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User)
body = models.TextField()
picture = models.ForeignKey(Picture)
View Comment<br/>
{% for c in comment %}
{% ifequal c.picture.id pet.id %}
<br>{{ c.body }}</li>
<br>{{ c.created}}</li>
<br>{{ c.user}}</li>
{% endifequal %}
{% endfor %}