I'm currently learning Django and I wanted to start off with a really simple blog app. I have a model for my post:
class Post(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
body = models.TextField()
Then I'm referencing it on my home page template:
{% extends 'base.html' %}
{% block content %}
{% for post in object_list %}
<div class="post-entry">
<h2>{{post.title}}</h2>
<p>{{post.body}}</p>
</div>
{% endfor %}
{% endblock content %}
I would like to make post.body to be only first 50 or so characters but post.body[:50] returns syntax error. How could I do that?
Try This:-
You can use
{{ post.body|truncatechars:50 }}
It will display only 50 characters of your Post Body
Related
I have a model called Section and a model called SectionInfo. Section has one field and that's name. A user will create a section by giving it a name. SectionInfo has a foreign key section_name which links it to the Section model. I have a few other fields inside SectionInfo such as things like detail, date_created, etc. What I am trying to accomplish here is using a for loop to display section names that have already been created inside or above some cards that I have set up in an html template. Then I want to use a nested loop to gather the data that is tied to that section name which is what the user inputs in for the SectionInfo model. I am able to display the section names correctly, but the issue im having is in the loop inside that loop. The same detail link is being displayed in every section that was made. Information should only be displayed in the chosen section for which it was made.
Here is a bit of code to help you understand what I am trying to accomplish.
Template file:
{% extends "base.html" %}
{% load bootstrap5 %}
{% load crispy_forms_tags %}
{% load static %}
{% block content %}
{% for i in object %}
{{ i.name}}
<div class="row">
<div class="col-sm-4">
<div class="card">
<div class="card-body">
{% for ii in object_2 %}
Details
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock content %}
Here is what I am getting displayed
whats being displayed
Here is the view that's being used
def section_info_detail(request, pk):
object = get_object_or_404(Section, id=pk)
object_2 = get_object_or_404(SectionInfo, id=pk)
context = {
'object': object,
'object_2':object_2,
}
return render(request, 'manufacturing/section_info_detail.html', context)
Models.py:
class Section(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class SectionInfo(models.Model):
section_name = models.ForeignKey(Section, on_delete=models.CASCADE)
detail = models.CharField(max_length=50)
text = models.TextField(max_length=2000)
date_created = models.DateField('Date created', auto_now_add=True)
date_updated = models.DateField('Date updated', auto_now=True)
Forms.py:
class SectionNameForm(forms.ModelForm):
class Meta:
model = Section
fields = [
'name',
]
class SectionInfoForm(forms.ModelForm):
class Meta:
model = SectionInfo
fields = [
'section_name',
'detail',
'text',
]
If any other information is needed, do tell.
<div class="row">
{% for object in object_list %}
<div class="col-sm-4">
<div class="card">
<div class="card-header">
<h1><strong>{{ object.name }}</strong></h1>
<hr>
</div>
<div class="card-body">
<div class="row">
{% for info in object.section_infos.all %}
<ul id="list">
<li>{{ info.date_created }}</li> |
<li>{{ info.detail|truncatechars:20 }}</li>
<hr>
</ul>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
This did it for me. So basically what my problem was I was not drilling down far enough to get the data that I needed to be displayed from the template. Also I had changed some things up in my models and had created a manyTomany and through field
I have Model Question and Answer.
What I want to accomplish is to be able to display it in the template in a way that shows like this. I would like to know a way to accomplish this. I'm trying my best to not let it loop the whole data in a model but rather one data at a time. I'm trying to make a qna data and make it display on a template. so having all the Questio data displayed before Answer data is not what I want. It has to be one by one for these two models. I'm getting kinda close...but I stil can't figure out how to accomplish this. Any help or advice would be greatly appreciated. Thank you in advance.
Q.title
Q.body
A.body
Q.title
Q.body
A.body
Q.title
Q.body
A.body
modesl.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
class Question(models.Model):
title= models.CharField(max_length= 100)
body= models.TextField()
date_posted= models.DateTimeField(default=timezone.now)
author= models.ForeignKey(User, on_delete= models.CASCADE)
def __str__(self):
return self.title
class Answer(models.Model):
body= models.TextField()
question= models.ForeignKey(Question, on_delete= models.CASCADE)
date_posted= models.DateTimeField(default=timezone.now)
author= models.ForeignKey(User, on_delete= models.CASCADE)
def __str__(self):
return self.body
qna.html template
{% extends "info/base.html" %}
{% block content %}
{% for question in questions %}
<h1> Q</h1>
<h3> {{ question.title }} </h3>
{% for answer in answers %}
<h1> A </h1>
<h3> {{ answer.body }}</h3>
{% endfor %}
{% endfor %}
{% endblock content %}
views.py
from django.shortcuts import render
from .models import Question, Answer
def qna(request):
context= {
'questions': Question.objects.all(),
'answers': Answer.objects.all(),
}
return render(request, 'qna/qna.html', context)
As Answer model has relation of ForeignKey with question you can directly access question model fields in reverse.Replace your code in html like below and check if same works for you.
{% extends "info/base.html" %}
{% block content %}
{% for answer in answers %}
<h1> Question:</h1>
<h3> title: {{ answer.question.title }} </h3>
<h3> body: {{ answer.question.body }} </h3>
<h1> Answer: </h1><h3> {{ answer.body }} </h3>
{% endfor %}
{% endblock content %}
Add related_name to model Answer that has ForeignKey with Question:
question= models.ForeignKey(Question, on_delete= models.CASCADE, related_name='my_answes')
in HTML file replace the second loop with :
{% for answer in question.my_answes.all %}
<h1> A </h1>
<h3> {{ answer.body }}</h3>
<hr>
{% endfor %}
I want to display 1 Parent Field with associated Child and further there Childs
I have a Model
class GrandParent(models.Model):
name= models.CharField(max_length=50)
....
class Parent(models.Model):
parent = models.ForeignKey(GrandParent, on_delete=models.CASCADE)
name= models.CharField(max_length=50)
....
class Child(models.Models):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
name= models.CharField(max_length=50)
...
I am able to render objects from Grand Parent But I m unable to link further Parent Class objects and Child class objects in templates
This approach I used in views.py
def list(request):
object_list = GrandParent.published.all()
...
return render('app/list.html')
def detail(request, post,):
post = get_object_or_404(GrandParent, slug=post,
status='published')
return render(request, 'app/detail.html',
{'post' : post,
...
})
Now how to link further Classes in Same Detail View But Associated with there Parent Classes using Foreign Key. I'm following Django docs but they only giving max 2 examples using python shell with just One subclass I m confused How to implement there in this structure. Or anyone have already developed any project specifically with this type of models so please share any link of repo or something, would be wonderful.
#list.html
{% extends "_base.html" %}
{% block title %} mysite{% endblock %}
{% block content %}
<h2>Content </h2>
<ul>
{% for post in object_list %}
<a href="{{ post.get_absolute_url }}">
<li>{{ post.name}}</li></a>
{% endfor %}
</ul>
{% endblock %}
#detail.html
{% extends "_base.html" %}
{% block title %} freeStreams {% endblock %}
{% block content %}
<div class="card-body">
<h1 class="card-title">{{ post.title }}</h1>
</div>
{% endblock %}
You can access from one to many in view template by for loop all child of it. In your case, with GrandParent by post.parent_set.all(). For Child by parent.child_set.all(). You can try first in terminal for check you have correct database and relation.
Add it inside block content
detail.html
{% for parent in post.parent_set.all() %}
<h1 class="card-title">{{ parent.name }}</h1>
{% for child in parent.child_set.all() %}
<h2 class="card-title">{{ child.name }}</h2>
{% endfor %}
{% endfor %}
I am using django-filter==2.1.0 for implementing search filter. I already implement it. But now i need to search by clicking checkbox not by search button. My codes are given below:
models.py
class Book(models.Model):
name = models.CharField(max_length=100)
publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
filters.py
class BookFilter(django_filters.FilterSet):
publication = django_filters.ModelMultipleChoiceFilter(queryset=Publication.objects.all(),
widget= forms.CheckboxSelectMultiple)
class Meta:
model = Book
fields = ['publication']
views.py
def test_view(request):
book_list = Book.objects.all()
book_filter = BookFilter(request.GET, queryset=book_list)
temp = book_filter.form
return render(request, 'test.html', {'filter': book_filter})
template
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block content %}
<form method="get">
{% for choice in filter.form.publication %}
<label>
{{ choice.tag }}
<span class="max-content-width">{{ choice.choice_label }}</span>
</label>
{% endfor %}
<button type="submit">Search</button>
</form>
<ul>
{% for book in filter.qs %}
<li>{{ book.name }}</li>
{% endfor %}
</ul>
{% endblock %}
It's working properly. But i want to add widget = forms.CheckboxInput(attrs={'onclick': 'this.form.submit();'}) in my filters.py for checkbox input. I don't understand how can i add another widget. Please help me to solve this problem.
Create a widget, write JavaScript script and use Media metaclass on widget to use it. After this just use your widget on your checkbox field.
I want to learn django and I should categorize my sql inputs according to my models.
For example I have some models like this:
class Author(models.Model):
authorName = models.CharField(max_length=30)
def __str__(self):
return self.authorName
class Book(models.Model):
author = models.ForeignKey(Authors, on_delete=models.CASCADE)
bookName = models.CharField(max_length=60)
downloadLink = models.FileField()
downloadCount = models.IntegerField(default=0)
def __str__(self):
return self.bookName
and I want to an output in my .html file like this;
Sherlock Holmes
A Study in Scarlet
The Sign of the Four
The Hound of the Baskervilles
Suzanne Collins
The Hunger Games
Catching Fire
Mockingjay
I tried this code in my html file but it doesn't work
<ul>
{% for author in all_authors %}
<h2>{{ author.authorName }}</h2>
{% for book in all_books %}
{% if book.author == author.authorName %}
<li>{{ book.bookName }}</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
My output is;
Sherlock Holmes
Suzanne Collins
Here is my view.py file;
def books(request):
return render(request,'../templates/library/library-template.html', {
'all_authors': Author.objects.all(),
'all_books': Book.objects.all(),
})
How can I fix it? Or are there any different solution for fix this?
Thank you.. :)
Your if statement will never be true, you are comparing an object and a string
{% if book.author == author.authorName %}
So you could change this to
{% if book.author == author %}
But this is still wasteful, you can just use the reverse lookup so you won't need the if statement at all
<ul>
{% for author in all_authors %}
<h2>{{ author.authorName }}</h2>
{% for book in author.book_set.all %}
<li>{{ book.bookName }}</li>
{% endfor %}
{% endfor %}
</ul>