Django Duplication objects - django

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 %}

Related

Django _set.all in template with one to many relationship

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 %}

Not able to display in Template the foreign key using ListView

I'm trying to display a photographic session with all of it photos, so I have the session name in one model and I have the pictures in
another model linked by a foreign key. I'm not able to display it in
the HTML I'm not sure if I'm using the ListView get_context_data
correctly and I'm certainly sure the the html code is not correct but
I have not found how to do it.
views.py
class SessionPictures(generic.ListView):
model = PostSession
template_name = 'photoadmin/gallery.html'
def get_context_data(self, **kwargs):
context = super(SessionPictures, self).get_context_data(**kwargs)
context['picture'] = Images.objects.all()
return context
models.py
class PostSession(models.Model):
session_name = models.CharField(max_length=25)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return str(self.session_name)
class Images(models.Model):
name = models.ForeignKey(
PostSession, related_name='images', on_delete=models.CASCADE, null=True, blank=True)
picture = models.ImageField(upload_to='pictures')
html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<h2>Images</h2>
<ul>
{% for session in object_list %}
<li>{{ session.session_name }}</li>
<ul>
<li>{{session.picture_set.all.url}}</li>
</ul>
{% endfor %}
</ul>
{% endblock %}
I'm expecting this:
Woods
picture1.url
picture2.url
picture3.url
Beach
Picture4.url
picture5.rul
As you already defined related_name="images" in Images model, so, session.images_set attribute won't work with PostSession.
class Images(models.Model):
name = models.ForeignKey(
PostSession,related_name='images', on_delete=models.CASCADE, null=True, blank=True)
Instead, use session.image.all in template(FYI: it returns a queryset, so you need to iterate through it to get the image object):
{% for session in object_list %}
<li>{{ session.session_name }}</li>
<ul>
{% for i in session.images.all %}
<li> i.picture.url </li>
{% endfor %}
</ul>
{% endfor %}
More information on reverse relation can be found in documentation.

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 %}