filter in django 2.0 - django

Hey I am writing app in django many blogs with many articles each but i dont know how to take artices which belongs to blog and write filter
My articles model
class Articles(models.Model):
title = models.CharField(max_length=150, verbose_name="Tytul")
content = models.TextField(verbose_name="Tekst")
published = models.DateTimeField(verbose_name="Data publikacji",auto_now=True)
image = models.FileField(upload_to="images",verbose_name="Obrazy",default=None)
blog = models.ForeignKey(Blogs,on_delete=models.CASCADE,null=True)
My blogs model
class Blogs(models.Model):
title = models.CharField(max_length=150, verbose_name="Tytul")
user = models.CharField(max_length=160, verbose_name="Uzytkownik")
blog.html
{% include 'base.html' %}
{% block blog %}
<h2>{{ blog.title }}</h2>
<div class="blog-info">
Tworca : {{ blog.user }}
</div>
{% block article %}
{% for a in article.blog_set.all %} <---- here
<div class="article">
Opublikowano : {{ a.published }}
</div>
<img src="{{ a.image.url }}" class="article-img">
<div class="article-intro">
<p>{{ a.content }}</p>
</div>
{% endfor %}
{% endblock %}
{% endblock %}
database

Related

many to one field self relationship

i used a self relationship inside model with foreignkey , purpose was to make a replyable comment , but idk how to use it in templates,
i mean whats different between 3 ManyToOne relationships i used in template , how can i know form send reply or comment?
model:
class Comment(models.Model):
#comments model
post = models.ForeignKey(Post,related_name='comments',on_delete=models.CASCADE)
text = models.CharField(max_length=300)
user = models.ForeignKey(get_user_model(),related_name='users',on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
parent = models.ForeignKey('self', null=True,related_name='reply',on_delete=models.SET_NULL)
class Meta():
verbose_name_plural = 'Comments'
ordering = ['date']
def __str__(self):
return self.test[:50]
template:
<div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button value="submit">Send</button>
</form>
</div>
<div>
{% for comment in object.comments.all %}
<p>{{ comment.text }}</p>
{% for reply in object.reply.all %}
<p>{{ reply.text }}</p>
{% endfor %}
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<button value="submit">reply</button>
</form>
{% endfor %}
</div>
{% endblock %}
can you a little explain how it works?
You can consider using a recursive solution in your code using with template tag, like this:
First define a template which will render the comment:
<!-- comments.html -->
{% for comment in comments %}
<p>{{ comment.text }}</p>
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<button value="submit">reply</button>
</form>
{% if comment.reply.exists %}
<ul>
{% include "comments.html" with comments=comment.reply.all %}
</ul>
{% endif %}
{% endfor %}
Then include it in the original template:
<div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button value="submit">Send</button>
</form>
</div>
<div>
{% include "comments.html" with comments=object.comments_only %}
</div>
Finally, only send the Comments which does not have parents,like this:
class Post(...):
...
def comments_only(self):
return self.comments.filter(parent__isnull=True)

My generic DetailView not showing list of items

I am following a django tutorial series, the music website contains the ListView which contains Albums(this is showing) but the DetailView Containing the list of songs in each Album is not showing.
I have tried changing the iteration name in the for loop but it still not working, the list shows when i am not using the generic method i.e using index and detail function instead of the IndexView and DetailView classes.
MY music.views Code
class IndexView(generic.ListView):
template_name='music/index.html'
def get_queryset(self):
return Albums.objects.all()
class DetailView(generic.DetailView):
model = Albums
template_name = 'music/detail.html'
My detail.html code which is supposed to show the list of songs but not working
{% extends 'music/base.html' %}
{% block title %} Album Details {% endblock %}
{% block body %}
<img src ="{{ all_album.alb_logo }}">
<h1>{{ all_album.alb_title }}</h1>
<ul>
{% for song in all_album.song_set.all %}
<li>{{ song.song_title }} </li>
{% endfor %}
</ul>
<br>
{% endblock %}
My index.html which shows the list of albums, this is working
{% extends 'music/base.html' %}
{% block body %}
<h2>List of Current albums available</h2>
<div class='container-fluid'>
<div class='row'>
{% for album in object_list %}
<div class='col-lg-4'>
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ album.alb_logo }}" >
<div class="card-body">
<h5 class="card-title">{{ album.alb_title }}</h5>
<p class="card-text">{{ album.alb_artist }}</p>
<a href="{% url 'music:detail' album.id %}" class="btn
btn-primary btn-sm">View details</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
My urls.py code#
urlpatterns = [
path('',views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]
The detail.html page is expected to show the list of songs in a selected album that is already in the database when clicked, but it is not showing.
You were using the wrong context variable name(all_album) inside the template, it should be object.
#detail.html
{% extends 'music/base.html' %}
{% block title %} Album Details {% endblock %}
{% block body %}
<img src="{{ object.alb_logo }}">
<h1>{{ object.alb_title }}</h1>
<ul>
{% for song in object.song_set.all %}
<li>{{ song.song_title }} </li>
{% endfor %}
</ul>
<br>
{% endblock %}
Reference: DetailView get_context_data() method--Django Doc

Django Image by Foreign Key and {% if / else %}

I trying to access the ImageField of a Model which is assigned via ForeignKey to another Model.
I have different Animal Apps in my Projects, with almost the same structure, like the following models.py. On the landingpage of My Project I want to display the last 3 entry of every (Species) Models with Name and Picture. If the Species has no Picture I would like to display the ImageField of the Farm, which is connected via ForeignKey to my species.
cows/models.py
class Farm(models.Model):
name = models.CharField(max_length=100)
farm_img = models.ImageField(upload_to='farm_images/',
max_length=255, null=True, blank=True)
class Cows(models.Model):
farm = models.ForeignKey(Farm, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100)
entry_date = models.DateField(null=True, blank=True)
cow_img = models.ImageField(upload_to='farm_images/',
max_length=255, null=True, blank=True)
Views.py
class HomeIndex(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context['chickens'] = Chicken.objects.order_by('-entry_date')[:3]
context['cows'] = Cows.objects.order_by('-entry_date')[:3]
context['cats'] = Cats.objects.order_by('-entry_date')[:3]
return context
home.html
<….>
{% for somecow in cows %}
<div class="col-3" id="p1">
<h2>{{ somecow.name }}</h2>
<h2>{{ somecow.entry_date }}</h2>
{% if somecow.cow_img %}
<img src="{{ somecow.cow_img.url }}" alt="Mod" height="100">
{% endif %}
</div>
{% endfor %}
<….>
Until here it worked.
But how can i access the FK.Model of the Model?
Or in other Words how can I tell Django:
“If you found no cow Picture in Cow.Model,then show a Farm picture from the assigned Farm.Model?”
As I understand I can access the assigned FK Models via
{% for something in MyModel1.MyModel2_set.all %}.
my approach for home.html
<….>
{% for somecow in cows %}
<div class="col-3" id="p1">
<h2>{{ somecow.name }}</h2>
<h2>{{ somecow.entry_date }}</h2>
{% if somecow.cow_img %}
<img src="{{ somecow.cow_img.url }}" alt="Mod" height="100">
{% else %}
{% for farm in somecow.farm_set.all %}
{% if farm.farm_img %}
<img src="{{ farm.farm_img.url }}" alt="Mod" height="100">
{% endif %}
{% endfor %}
{% endif %}
</div>
{% endfor %}
<….>
So far I received no error Message, but I also see no Farm Image. I am sure I mixed something up in home.html. On the other Side I think I maybe I missed something in my view, something like MyModel.objects.all()
I am thankful for every hint.
You're overcomplicating things. There is only a single farm per cow: you just need to access it directly.
{% else %}
{% if cow.farm.farm_img %}
<img src="{{ cow.farm.farm_img.url }}" alt="Mod" height="100">
{% endif %}
{% endif %}

is_paginated not working properly for class based views in Django

book_list.html
{% extends "base.html" %}
{% block content %}
<h3> Available books </h3>
{% if book_list %}
<ul>
{% for book in book_list %}
<li> {{book.title }} <small> by {{book.author }}</small></li>
<p>{{ book.summary }}
{% endfor %}
<ul>
{% endif %}
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
previous
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
{% endif %}
</span>
</div>
{% else %}
<h4> pagination not working</h4>
{% endif %}
{% endblock %}
class in views.py :
class BookListView(generic.ListView):
model = Book
paginate_by = 2
queryset =Book.objects.all()
urls.py :
urlpatterns =[
url('^$',views.index, name ='index'), # matching with an empty string
url('^books/$',views.BookListView.as_view(),name ='books'), #the one to which I am adding the paginator
url('^book/(?P<pk>\d+)/$',views.BookDetailView.as_view(),name='book-detail'),
]
Book model :
class Book(models.Model):
title=models.CharField(max_length=100)
author = models.ForeignKey('Author',on_delete=models.SET_NULL,null = True)
summary = models.TextField(max_length=200,help_text="Enter the description")
isbn = models.CharField('ISBN',max_length=13 ,help_text='13 Character ISBN number' )
genre = models.ManyToManyField(Genre,help_text = 'selct a genre for this book')
class Meta:
ordering =["title"]
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book-detail',args=[str(self.id)] )
The book_list gets rendered perfectly, the problem is with the paginator, the is_paginated condition is not working and it executes the else statement, I have been trying for more than 3 hours, but couldn't find a solution, What Am I missing here ?
Django version : 1.11.2
Python : 3.5
Edit :
update 1: The problem was the paginate_by value was two, and the total items to display was also two hence it didn't initiate the is_paginated tag,It worked fine when I added one item more than paginate_by value.
use this, you had some problem with the if condition
{% extends "base.html" %}
{% block content %}
<h3> Available books </h3>
{% if object_list %}
<ul>
{% for book in object_list %}
<li> {{book.title }} <small> by {{book.author }}</small></li>
<p>{{ book.summary }}
{% endfor %}
<ul>
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
previous
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
{% endif %}
</span>
</div>
{% else %}
<h4> pagination not working</h4>
{% endif %}
{% else %}
<h4> No book</h4>
{% endif %}
{% endblock %}

Django Reverse Query in Template

I have models like this
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __unicode__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
I want to list all blogs in a page. I have written a view such that
def listAllBlogs(request):
blogs= Blog.objects.all()
return object_list(
request,
blogs,
template_object_name = "blog",
allow_empty = True,
)
And I can display tagline of blog such that in view
{% extends "base.html" %}
{% block title %}{% endblock %}
{% block extrahead %}
{% endblock %}
{% block content %}
{% for blog in blog_list %}
{{ blog.tagline }}
{% endfor %}
{% endblock %}
But I would like to show, such thing blog__entry__name but I don't know how can I achive this in template.
Also, there may be no entry in a blog. How can I detect in template ?
Thanks
To access blog entries (Related Manager): blog.entry_set.all
To do other actions if blog have no entries, you have the {% empty %} tag that is executed when the set is empty.
{% block content %}
{% for blog in blog_list %}
{{ blog.tagline }}
{% for entry in blog.entry_set.all %}
{{entry.name}}
{% empty %}
<!-- no entries -->
{% endfor %}
{% endfor %}
{% endblock %}
based on your code you could do the following.
{% block content %}
{% for blog in blog_list %}
{{ blog.tagline }}
{% for entry in blog.entry_set.all %}
{{entry.name}}
{% endfor %}
{% endfor %}
{% endblock %}