Django list class instances matching parent - python

I'm new to Django, so any help is appreciated. I have one class Gym and a second class Route (rock climbing gym and climbing routes). Each gym can contain multiple routes, but each route can only belong to one gym. I can list available gyms and click on one to go to the gym page, but I want to list all of the routes that belong to it and can't figure out how.
# /gym/models.py
from django.db import models
from django.shortcuts import reverse
class Gym(models.Model):
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='gym', default='default_route.jpg')
address = models.CharField(max_length=200)
def get_absolute_url(self):
return reverse('gym:detail', kwargs={'pk': self.pk})
def __str__(self):
return self.name
# route/models.py
from django.db import models
from .utils import generate_qrcode
class Route(models.Model):
Gym = models.ForeignKey('gym.Gym', on_delete=models.CASCADE, null=True)
grade = models.CharField(max_length=10)
hold_color = models.CharField(max_length=20, default='')
rating = models.PositiveIntegerField()
date = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to='routes', default='default_route.jpg')
def __str__(self):
return str(self.pk)
# gym/views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from .models import Gym
from route.models import Route
def gym_list_view(request):
# Can filter this for specific gyms
qs = Gym.objects.all()
return render(request, 'gym/index.html', {'gym_list': qs})
def gym_detail_view(request, pk):
gym_obj = Gym.objects.get(pk=pk)
# This is where I don't know how to get the routes that belong to the current gym
routes_obj = Route.objects.get(pk=pk)
return render(request, 'gym/detail.html', {'gym_object': gym_obj, 'routes_obj': routes_obj})
# gym/templates/gym/detail.html
{% extends "base.html" %}
{% block title %}
{{ gym_object.pk }}
{% endblock title %}
{% block content %}
Gym ID: {{gym_object.pk }} <br><br>
<h3> {{ gym_object.name }} </h3>
{{ gym_object.address }}
<br><br>
<h4>Routes</h4>
route_obj: {{ routes_obj }}
{% endblock content %}

def gym_detail_view(request, pk):
gym_obj = Gym.objects.get(pk=pk)
# This is where I don't know how to get the routes that belong to the current gym
routes = gym_obj.route_set.all()
return render(request, 'gym/detail.html', {'gym_object': gym_obj, 'routes': routes})
Try this

Related

Page rendering with model.py but not working after data is added in the models through admin portal

I am working on MDN Django tutorial on LocalLibrary.
I am using get_absolute_url to render generic ListView and DetailView page.
App is rendering page with else statement i.e. There are no books in the library.
But when I add books in the library through admin portal in my models. Same pages are not rendering and reflecting below error
NoReverseMatch at /catalog/books/
Reverse for 'book-detail' not found. 'book-detail' is not a valid view function or pattern name.
Please find the models.py as follows
import uuid # Required for unique book instances
from django.db import models
# Create your models here.
# Used to generate URLs by reversing the URL patterns
from django.urls import reverse
class Genre(models.Model):
"""Model representing a book genre."""
name = models.CharField(
max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
def __str__(self):
"""String for representing the Model object."""
return self.name
class Language(models.Model):
name = models.CharField(max_length=200, help_text='Enter a book language(e.g. English)')
def __str__(self):
return self.name
class Book(models.Model):
"""Model representing a book (but not a specific copy of a book)."""
title = models.CharField(max_length=200)
# Foreign Key used because book can only have one author, but authors can have multiple books
# Author as a string rather than object because it hasn't been declared yet in the file
author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(
max_length=1000, help_text='Enter a brief description of the book')
isbn = models.CharField('ISBN', max_length=13, unique=True,
help_text='13 Character ISBN number')
# ManyToManyField used because genre can contain many books. Books can cover many genres.
# Genre class has already been defined so we can specify the object above.
genre = models.ManyToManyField(
Genre, help_text='Select a genre for this book')
language = models.ManyToManyField(
Language, help_text='Select Language for this book')
def __str__(self):
"""String for representing the Model object."""
return self.title
def get_absolute_url(self):
"""Returns the url to access a detail record for this book."""
return reverse('book-detail', kwargs= {'pk': str(self.id)})
def display_genre(self):
"""Create a string for the Genre. This is required to display genre in Admin."""
return ', '.join(genre.name for genre in self.genre.all()[:3])
display_genre.short_description = 'Genre'
def get_language(self):
"""Create a string for the Genre. This is required to display genre in Admin."""
return ', '.join(language.name for language in self.language.all()[:3])
get_language.short_description = 'Language'
class BookInstance(models.Model):
"""Model representing a specific copy of a book (i.e. that can be borrowed from the library)."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4,
help_text='Unique ID for this particular book across whole library')
book = models.ForeignKey('Book', on_delete=models.RESTRICT, null=True)
imprint = models.IntegerField()
due_back = models.DateField(null=True, blank=True)
LOAN_STATUS = (
('m', 'Maintenance'),
('o', 'On loan'),
('a', 'Available'),
('r', 'Reserved'),
)
status = models.CharField(
max_length=1,
choices=LOAN_STATUS,
blank=True,
default='m',
help_text='Book availability',
)
class Meta:
ordering = ['due_back']
def __str__(self):
"""String for representing the Model object."""
return f'{self.id} ({self.book.title})'
class Author(models.Model):
"""Model representing an author."""
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('Died', null=True, blank=True)
class Meta:
ordering = ['last_name', 'first_name']
def get_absolute_url(self):
from django.urls import reverse
"""Returns the url to access a particular author instance."""
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
"""String for representing the Model object."""
return f'{self.last_name}, {self.first_name}'
Attached is the urls.py
from django.urls import path
from catalog import views
from catalog.views import BookListView, BookDetailView
app_name = 'catalog'
urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='books'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
path('authors/', views.AuthorListView.as_view(), name='authors'),
path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail'),
]
Views.py
from django.shortcuts import get_object_or_404
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.http import HttpResponse
from django.shortcuts import render
from catalog.models import *
def index(request):
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()
num_genre = Genre.objects.all()
num_instances_available = BookInstance.objects.filter(status__exact='avail').count()
num_authors = Author.objects.count()
context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
'num_genre': num_genre,
}
return render(request, 'catalog/index.html', context=context)
class BookListView(ListView):
model = Book
paginate_by = 2
class BookDetailView(DetailView):
model = Book
class AuthorListView(ListView):
model = Author
class AuthorDetailView(DetailView):
model = Author
Template of book_list.html
This is saved as per this method
catalog/templates/catalog/book_list.html
{% extends "catalog/base.html" %}
{% block title %}
<title>List of Books</title>
{% endblock %}
{% block content %}
<h1>Book List</h1>
{% if book_list %}
<ul>
{% for book in book_list %}
<li>
{{ book.title }}
({{ book.author }})
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no books in the library.</p>
{% endif %}
{% endblock %}
book_detail.html
This is saved as per this method
catalog/templates/catalog/book_detail.html
{% block content %}
<h1>Title: {{ book.title }}</h1>
<p><strong>Author:</strong> {{ book.author }}</p>
<p><strong>Summary:</strong> {{ book.summary }}</p>
<p><strong>ISBN:</strong> {{ book.isbn }}</p>
<p><strong>Language:</strong> {{ book.language }}</p>
<p><strong>Genre:</strong> {{ book.genre.all|join:", " }}</p>
<div style="margin-left:20px;margin-top:20px">
<h4>Copies</h4>
{% for copy in book.bookinstance_set.all %}
<hr>
<p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'd' %}text-danger{% else %}text-warning{% endif %}">{{ copy.get_status_display }}</p>
{% if copy.status != 'a' %}<p><strong>Due to be returned:</strong> {{copy.due_back}}</p>{% endif %}
<p><strong>Imprint:</strong> {{copy.imprint}}</p>
<p class="text-muted"><strong>Id:</strong> {{copy.id}}</p>
{% endfor %}
</div>
{% endblock %}```
I also find error on the same page for bootstrap link which is getting extended from base file and working fine with index.html
whereas on books.html page
It is showing this error
In template /Users/rishipalsingh/Projects/notes/mdndjango/mdn/catalog/templates/catalog/base.html, error at line 7
base.html
```
Thank you
You have namespaced your urls by writing:
app_name = 'catalog'
Hence reverse('book-detail', ...) will not work and you need to specify the namespace along with the url name, hence it should be:
reverse('catalog:book-detail', kwargs= {'pk': str(self.id)})
Similarly for the author:
reverse('catalog:author-detail', args=[str(self.id)])

Django Select2MultipleWidget leads to form continuously trying to load

I'm trying to incorporate Select2 into my django form -- specifically ModelSelect2MultipleWidget -- so that the user can associate multiple event objects to another model (like CheckboxSelectMultiple). The associated models are:
from django.contrib.auth import get_user_model
from django.db import models
class F4Events(models.Model):
name = models.CharField(max_length=300)
handling_type = models.ManyToManyField(WaferHandlingType)
def __str__(self):
return self.name
class ToolPm(models.Model):
ceid = models.ForeignKey(CEID, on_delete=models.CASCADE)
name = models.CharField(max_length=250)
wafer_handling = models.BooleanField(default=True)
wafer_based = models.BooleanField(default=False)
frequency = models.FloatField(blank=True, null=True)
handling_type = models.ManyToManyField(WaferHandlingType, blank=True)
user_edited = models.BooleanField(default=False)
pm_f4_events = models.ManyToManyField('F4Events', blank=True)
def __str__(self):
return str(self.name) if self.name else ''
class Meta:
ordering = ('ceid', 'name')
My forms.py file is:
from django import forms
from .models import Entity, ToolPm, CEID, PDL, F4Events, WaferHandlingType
from django_select2 import forms as s2forms
class F4EventWidget(s2forms.ModelSelect2MultipleWidget):
search_fields = [
'name__icontains',
]
attrs = {'data-placeholder': 'Please Choose F4 Events'}
class PMForm(forms.ModelForm):
class Meta:
model = ToolPm
fields = ['wafer_handling', 'wafer_based', 'handling_type', 'pm_f4_events']
widgets = {'handling_type': forms.CheckboxSelectMultiple,
'pm_f4_events': F4EventWidget
}
my view.py is:
from datetime import datetime, timedelta
from django.db.models import Sum
from django.http import JsonResponse, HttpResponseRedirect
from django.http.response import HttpResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.views import View
from django.views.generic import ListView
from django_filters.views import FilterView
from pages.filter import CeidFilter, PmRunDateFilter
from tools.forms import EntityForm, PMForm, CEIDForm, PDLAddForm
from tools.models import CEID, Entity, F4Events, ToolPm, WaferHandlingType, PmRunDate
from django.urls import reverse
class UserCeidPMUpdate(View):
template_name = 'tools/update_pm_attributes.html'
def get(self, request, username, pk, pm_id):
pm = ToolPm.objects.get(pk=pm_id)
form = PMForm(request.GET or None, instance=pm)
return render(request, self.template_name, {'form': form, 'pm': pm, })
def post(self, request, username, pk, pm_id):
pm = ToolPm.objects.get(pk=pm_id)
pm.user_edited = True
pm.save()
form = PMForm(request.POST or None, instance=pm)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('pm_view', kwargs={'username': username, 'pk': pm.ceid.id}))
return render(request, self.template_name, {'form': form, 'pm': pm, })
lastly, my .html file is:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form method="post">
<p>Process: {{ pm.ceid.process }}</p>
<p>CEID: {{ pm.ceid.ceid }}</p>
<p>Name: {{ pm.name }}</p>
<p>Frequency: {{ pm.frequency }}{% if pm.wafer_based %} wafers {% else %} days {% endif %}</p>
<p>Score: {{ pm.score }}</p>
{% csrf_token %}
{{ form }}
<input type="submit" class="btn btn-success" value="Update PM"><button type="button" class="btn btn-primary">Go Back</button>
</form>
{% endblock content %}
If I switch the pm_f4_events widget to a CheckboxSelectMultiple or a ModelSelect2Widget, the code works.
However, when I try to use a ModelSelect2MultipleWidget, the form continually tries to load but cannot and eventually just times out.
There are ~5000 items within the F4Events model, so that may have something to do with it. Any help to point me in the right direction would be greatly appreciated!
You can empty the pm_f4_events field's choices in the __init__ method:
class PMForm(forms.ModelForm):
class Meta:
model = ToolPm
fields = ['wafer_handling', 'wafer_based', 'handling_type', 'pm_f4_events']
widgets = {
'handling_type': forms.CheckboxSelectMultiple,
'pm_f4_events': s2forms.ModelSelect2MultipleWidget(
model=F4Events,
search_fields=["name__icontains",],
attrs = {'data-placeholder': 'Please Choose F4 Events'}
)
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
choices_F4Events = []
pm_f4_events_field = self.fields["pm_f4_events"]
# selected values
selected_F4Events = self.data.getlist("pm_f4_events") or self.initial.get("pm_f4_events")
if selected_F4Events:
# check of selected values not object
if not isinstance(selected_F4Events[0], F4Events):
selected_F4Events = pm_f4_events_field.queryset.filter(pk__in=selected_F4Events)
choices_F4Events = [(item.pk, item.name) for item in selected_F4Events]
# assign selected values or empty list
pm_f4_events_field.choices = choices_F4Events
Has been tested on my server, works well.

ValueError at /ads/ad/2/comment

I am trying to add comment to an Ad posted by a user. When I press the comment button, it is showing the error.
Here's my models.py
from django.db import models
from django.core.validators import MinLengthValidator
from django.contrib.auth.models import User
from django.conf import settings
class Ad(models.Model):
title = models.CharField(
max_length=200,
validators=[MinLengthValidator(2, "Title must be greater than 2 characters")]
)
price = models.DecimalField(max_digits=7, decimal_places=2, null=True)
text = models.TextField()
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#picture
picture = models.BinaryField(null=True, blank=True, editable=True)
content_type = models.CharField(max_length=256, null=True, help_text='The MIMEType of the file')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
comments = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Comment', related_name='comments_owned')
#show up in the admin list
def __str__(self):
return self.title
class Comment(models.Model) :
text = models.TextField(
validators=[MinLengthValidator(3, "Comment must be greater than 3 characters")]
)
ad = models.ForeignKey(Ad, on_delete=models.CASCADE)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# Shows up in the admin list
def __str__(self):
if len(self.text) < 15 :
return self.text
return self.text[:11] + ' ...'
Here's my forms.py
# commentForm
from django import forms
from ads.models import Ad, Comment
from django.core.files.uploadedfile import InMemoryUploadedFile
from ads.humanize import naturalsize
from django.core import validators
from django.core.exceptions import ValidationError
...
class CommentForm(forms.Form):
comment = forms.CharField(required=True, max_length=500, min_length=3, strip=True)
class Meta:
model = Comment
fields = ['text']
Here's my views.py
from ads.models import Ad, Comment
from ads.owner import OwnerListView, OwnerDetailView, OwnerCreateView, OwnerUpdateView, OwnerDeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.views import View
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy, reverse
from django.http import HttpResponse
from ads.forms import CreateForm, CommentForm
class AdDetailView(OwnerDetailView):
model = Ad
def get(self, request, pk):
a = Ad.objects.get(id=pk)
comments = Comment.objects.filter(ad=a).order_by('-updated_at')
comment_form = CommentForm()
context = {'ad': a, 'comments':comments, 'comment_form':comment_form}
return render(request, 'ads/ad_detail.html', context)
....
class CommentCreateView(LoginRequiredMixin, View):
def post(self, request, pk):
ad = get_object_or_404(Ad, id=pk)
comment = Comment(text=request.POST['comment'], owner=request, ad=ad)
comment.save()
return redirect(reverse('ads:ad_detail', args=[pk]))
class CommentDeleteView(OwnerDeleteView):
model = Comment
def get_success_url(self):
ad = self.object.ad
return reverse('ads:ad_detail', args=[ad.id])
And finally my templates ad_detail.html
{% if user.is_authenticated %}
<br clear="all"/>
<p>
{% load crispy_forms_tags %}
<form method="post" action="{% url 'ads:ad_comment_create' ad.id %}">
{% csrf_token %}
{{ comment_form|crispy }}
<input type="submit" value="Submit">
<input type="submit" value="All Ads" onclick="window.location.href='{% url 'ads:all' %}'; return false;">
</form>
</p>
{% endif %}
{% for comment in comments %}
<p> {{ comment.text }}
({{ comment.updated_at|naturaltime }})
{% if user == comment.owner %}
<i class="fa fa-trash"></i>
{% endif %}
</p>
{% endfor %}
After clicking on the submit button, it's supposed to be taking to ads:all but instead throwing an error.
In case you also want to check urls.py
urlpatterns = [
path('', views.AdListView.as_view()),
path('ads', views.AdListView.as_view(), name='all'),
...
#comments
path('ad/<int:pk>/comment', views.CommentCreateView.as_view(), name='ad_comment_create'),
path('comment/<int:pk>/delete', views.CommentDeleteView.as_view(success_url=reverse_lazy('ads')), name='ad_comment_delete'),
]
You should be using ModelForm instead of Form here.
class CommentForm(forms.ModelForm):
comment = forms.CharField(required=True, max_length=500, min_length=3, strip=True)
class Meta:
model = Comment
fields = ['text']
And change your view
class CommentCreateView(LoginRequiredMixin, View):
def post(self, request, pk):
form = CommentForm(request.POST)
ad = get_object_or_404(Ad, id=pk)
comment = form.save(commit=False)
comment.ad = ad
comment.owner = request.user
comment.save()
return redirect('ads:ad_detail', ad.pk)
In you CommentCreateView, your owner is recieving request that was the reason you were shown that error. So:
comment = Comment(text=request.POST['comment'], owner=request.user, ad=ad)

Class Views and NoReverseMatch

I am new to coding and especially new to working with Django. I want to build a small "forum" for me and the other students and it works pretty fine.
There is just one error I encounter over and over:
Exception Type: NoReverseMatch
Exception Value: Reverse for 'thread-create' with
arguments '('',)' not found. 1 pattern(s) tried: ['forum/(?P<pk>[0-9]+)/add/$']
I can work around it using functions instead of class based Views, but I doubt that's how it's supposed to be done.
I have the feeling I am missing something very important while working with class views.
I really would appreciate if someone could help me out :-)
It's the links that are not working:
{% url 'user-posts' thread.author.username %}
and more importantly:
{% url 'forum:thread-create' thread.id %}
What's also not working while using classes is:
{% for thread in thema.thread_set %} (works with the functions)
(I only want to see the threads that are bind to a certain thema. That also works pretty well with functions).
And you might also be asking why I don't just use the function based views:
I want to know what am I doing wrong
I want to be able to easy paginate my site.
Code:
# models.py
from django.db import models
from django.urls import reverse
from PIL import Image
from django.utils import timezone
from django.contrib.auth.models import User
class Thema(models.Model):
themengebiet = models.CharField(max_length=350)
beschreibung = models.TextField()
themen_logo = models.FileField(max_length=350, upload_to="logos", default='default.jpg')
erstellt_am = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.themengebiet
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.themen_logo.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.themen_logo.path)
class Thread(models.Model):
thema = models.ForeignKey(Thema, on_delete=models.CASCADE)
titel = models.CharField(max_length=350)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
erstellt_am = models.DateTimeField(default=timezone.now)
thread_logo = models.ImageField(upload_to="logos", d efault='default.jpg')
def get_absolute_url(self):
return reverse('forum:thread-page', kwargs={'pk': self.thema.id})
def __str__(self):
return self.titel
class Posting(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
titel = models.CharField(max_length=350)
erstellt_am = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
inhalt = models.TextField()
def __str__(self):
return self.titel
views.py
from django.views import generic
from django.views.generic import CreateView, UpdateView, DeleteView, ListView
from .models import Thema, Thread, Posting
from django.shortcuts import render, get_object_or_404
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.core.paginator import Paginator
class ThemenView(ListView):
template_name = 'forum/posts_original.html'
context_object_name = 'all_themen'
def get_queryset(self):
return Thema.objects.all()
class ThemaCreate(CreateView):
model = Thema
fields = ['themengebiet', 'beschreibung', 'themen_logo']
success_url = "/forum/"
class ThreadCreate(CreateView):
model = Thread
fields = ['thema', 'titel', 'erstellt_am']
success_url = reverse_lazy('forum:posts_original')
def get_object(self):
return Thread.objects.get(pk=self.kwargs['pk'])
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostCreate(CreateView):
model = Posting
fields = ['thread', 'titel', 'inhalt', 'erstellt_am']
success_url = "/forum/"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class ThreadView(ListView):
model = Thread
context_object_name = 'threads'
template_name = 'forum/thread.html'
success_url = reverse_lazy('forum:posts_original')
def get_object(self):
return Thread.objects.get(pk=self.kwargs['pk'])
class PostView(ListView):
model = Posting
context_object_name = 'posts'
template_name = 'forum/posts.html'
urls.py
from django.urls import path
from . import views
app_name = 'forum'
urlpatterns = [
# /forum/
path('', views.ThemenView.as_view(), name='posts_original'),
# forum/id/
path('<int:pk>/', views.ThreadView.as_view(), name='thread-page'),
# forum/thread/add
#path('<int:pk>/add/', views.thread_create, name='thread-create'),
# forum/id//id
path('thread/<int:pk>/', views.PostView.as_view(), name='post-page'),
path('add/', views.ThemaCreate.as_view(), name='thema-create'),
path('<int:pk>/add/', views.ThreadCreate.as_view(), name='thread-create'),
path('thread/<int:pk>/add/', views.PostCreate.as_view(), name='post-create'),
]
'''
def thread(request, pk):
try:
thema = get_object_or_404(Thema, pk=pk)
except Thema.DoesNotExist:
raise Http404("Thema existitiert nicht")
return render(request, 'forum/thread.html', {'thema': thema})
def post(request, pk):
try:
thread = get_object_or_404(Thread, pk=pk)
except Thread.DoesNotExist:
raise Http404("Thema existitiert nicht!")
return render(request, 'forum/posts.html', {'thread': thread})
'''
{% extends "blog/base.html" %}
{{ threads }}
{% block content %}
Zurück zur Themenübersicht
{% for thread in threads %}
<article class="media content-section">
<img class="rounded-circle article-img" src= "{{ thread.thread_logo.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' thread.author.username %}">{{ thread.author }}</a>
<small class="text-muted">{{ thread.erstellt_am|date:"d. F Y" }}</small>
</div>
<h2><a class="article-title" href=" {% url 'forum:post-page' thread.id %}">{{ thread.titel }}</a></h2>
<p class="article-content">Thema: {{ thread.thema }}</p>
</div>
</article>
{% endfor %}
<form action="{% url 'forum:thread-create' thread.id %}" method="post" enctype="multipart/form-data" style="display: inline;">
{% csrf_token %}
Thread hinzufügen
</form>
{% endif %}
{% endblock content %}

import data of models.py with 2 class into template

I am a amature django developer. I have a model with two class called "Post" and "Catagory". I want to read Category items in my template. How can I import my category in my template and show it's data in my page?
models.py
from django.db import models
from taggit.managers import TaggableManager
class Category(models.Model):
title = models.CharField(max_length=40)
def __unicode__(self):
return self.title
class Post (models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
date = models.DateTimeField()
tags = TaggableManager ()
cats = models.ManyToManyField(Category)
def __unicode__ (self):
return self.title
Thank you.
If you are using class based views and want to list all categories you could do:
# urls.py
url(regex=r'^category/$',
view=CategoriesListView.as_view(),
name='category_list_all'),
# views.py
class CategoriesListView(ListView):
model = Category
# category_list.html
<h2>Category list</h2>
<ul>
{% for cat in category_list %}
<li>
{{ cat.category }}
</li>
{% endfor %}
</ul>
You would place the html file in <project_route>/<app_name>/templates/<app_name>/ or <project_route>/templates/<app_name>/
If you have an existing function based view that's working with the Post model then you can just do something like:
# views.py
...
post = get_object_or_404(Post, pk=pass_in_pk)
return render(request, 'post.html', {'post': post})
# post.html
<h2>Category list</h2>
<ul>
{% for category in post.cats %}
<li>{{ category.title }}</li>
{% endfor %}
</ul>
If you have a class based view based on a Post model using the DetailView then you can also use the above html, just place it in post_detail.html in the appropriate folder.
It`s like get the category value and assign into settings and passed into view html will work
def viewfuncion(request):
template_vars = {}
settings = Category.objects.get(pk=1)
template_vars['title_show'] = settings.title
t = loader.get_template('view.html')
c = Context(template_vars)
return HttpResponse(t.render(c), content_type = "application/xhtml")
So in your HTML { title_show } will print the content

Categories

Resources