I used get_absolute_url in my app but it works only on admin site (by button view on site). On my website, the hyperlink is not responding. I've checked every line of code a couple of times and it seems like everything's fine. Does anyone know why it doesn't works?
models.py
class CrashReport(models.Model):
number_id = models.AutoField(primary_key=True)
date_notice = models.DateField(auto_now=False, auto_now_add=False)
SHIFT_NUMBER = (
('I', 'Zmiana I (6:00 - 14:00)'),
('II', 'Zmiana II (14:00 - 22:00)'),
('III', 'Zmiana III (22:00 - 06:00)'),
)
which_shift = models.CharField(
max_length=3,
choices=SHIFT_NUMBER,
blank=True,
default='I',
help_text='Zmiana.'
)
who_notice = models.ManyToManyField(Author, help_text='Select a occupation for this employee')
description = models.TextField(max_length=1000, help_text='Please type what happened')
which_stuff = models.ManyToManyField(Device, help_text='Select a exactly devices')
PROCESSING_STATUS = (
('o', 'Otwarty'),
('p', 'Przetwarzanie'),
('z', 'Zakonczony'),
)
status_notice = models.CharField(
max_length=1,
choices=PROCESSING_STATUS,
blank=True,
default='o',
help_text='Status dokumentu.'
)
def __str__(self):
return f'ZGL /{self.number_id} / {self.which_stuff.all()} / {self.date_notice}'
def get_absolute_url(self):
return reverse('crashreport-detail', args=[str(self.number_id)])
views.py
from django.shortcuts import render
from django.views import generic
from .models import CrashReport
def index(request):
"""View function for home page of site."""
# Generate counts of some of the main objects
num_crashreports = CrashReport.objects.all().count()
# num_instances = BookInstance.objects.all().count()
# Opens Crashreports (status = 'o')
# num_crashreport_open = CrashReport.objects.filter(status__exact='o').count()
context = {
'num_crashreports': num_crashreports,
# 'num_crashreports_processing': num_crashreports_processing,
# 'num_crashreports_open': num_crashreports_open,
}
# Render the HTML template index.html with the data in the context variable
return render(request, 'dokumenty/index.html', context=context)
class CrashReportsListView(generic.ListView):
model = CrashReport
context_object_name = 'crash_reports_list' # your own name for the list as a template variable
queryset = CrashReport.objects.filter()[:5] # Get 5 crash reports
class CrashReportsDetailView(generic.DetailView):
model = CrashReport
urls.py
from django.urls import path, reverse
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('crashreports/', views.CrashReportsListView.as_view(), name='crashreports'),
path('crashreport/<int:pk>', views.CrashReportsDetailView.as_view(), name='crashreport-detail'),
crashreport_list.html
{% extends 'baza.html' %}
{% block content %}
<h>Witam w Systemie Ewidencji Maria Awaria Service - Raporty</h>
<h1>Zgłoszenia</h1>
{% if crash_reports_list %}
<ul>
{% for crashreports in crash_reports_list %}
<li>
ZGL /{{ crashreports.number_id }} / {{ crashreports.which_stuff.all|join:", " }} / {{crashreports.date_notice}},
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no crash reports in the system.</p>
{% endif %}
{% endblock %}
It should be
....
not href="{{ crashreport.get_absolute_url }}" because you are using crashreports when iterating in for loop:
{% for crashreports in crash_reports_list %}
^^^^^^^^^^^^
Related
I am trying to add a comment section to add a comment section to my blog detail using django but when i run my server i get no error in the development server and the comments are not being displayed. I added the comments from my admin site.
The snippet of my code is below.
views.py
from .models import Post
from django.utils import timezone
from .forms import PostForm, CommentsForm
from django.contrib.auth.decorators import user_passes_test
# Create your views here.
def home(request):
return render (request, 'blogapp/home.html')
def blog_list(request):
post = Post.objects.order_by('-published_date')
context = {
'posts':post
}
return render(request, 'blogapp/blog_list.html', context)
def blog_detail(request, pk=None):
detail = Post.objects.get(pk=pk)
context = {
'detail': detail
}
return render(request, 'blogapp/blog_detail.html', context)
def add_post(request, pk=None):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid:
body = form.save(commit=False)
body.published_date = timezone.now()
body.save()
return redirect('blog_list')
form = PostForm()
else:
form = PostForm()
context = {
'form': form
}
return render(request, 'blogapp/add_post.html', context)
def add_comments(request, pk=None):
if request.method == "POST":
form = CommentsForm(request.POST)
if form.is_valid:
comment = form.save(commit=False)
comment.date_added = timezone.now()
comment.save()
return redirect('blog_detail')
form = CommentsForm()
else:
form = CommentsForm()
context = {
'form': form
}
return render(request, 'blogapp/add_comments.html', context)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name="homepage"),
path('blog/', views.blog_list, name="blog_list"),
path('blog/post/<int:pk>/', views.blog_detail, name="blog_detail"),
path('blog/add_post/', views.add_post, name="add_post"),
path('blog/add_comments/', views.add_comments, name="add_comments"),
]
forms.py
from django import forms
from .models import Post, Comments
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('author', 'title', 'post_description', 'image', 'image_description', 'body',)
class CommentsForm(forms.ModelForm):
class Meta:
model = Comments
fields = ('post', 'name', 'body',)
models.py
from django.db import models
from django.utils import timezone
# Create your models here.
class Post(models.Model):
author = models.ForeignKey('auth.user', on_delete=models.CASCADE)
title = models.CharField(max_length=300)
body = models.TextField()
post_description = models.CharField(max_length=500, blank=True, null=True)
image = models.ImageField(blank=True, null=True, upload_to="image/")
image_description = models.CharField(max_length=500, blank=True, null=True)
published_date = models.DateTimeField(default=timezone.now, blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
class Comments(models.Model):
post = models.ForeignKey('Post', related_name="comments", on_delete=models.CASCADE)
body = models.TextField()
name = models.CharField(max_length=300)
date_added = models.DateTimeField(default=timezone.now, blank=True, null=True)
def __str__(self):
return '%s - %s' % (self.post.title, self.name)
blog_detail.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<article>
<strong>
<h1><b>{{ detail.title }}</b></h1>
</strong>
<h3>POST AUTHOR: {{ detail.author }}</h3>
<h4><i>{{ detail.post_description }}</i></h4>
<h4>PUBLISHED:{{ detail.published_date }}</h4>
<p>
<hr>
{% if detail.image %}
<center>
<br>
<img src="{{ detail.image.url }}" width="1000" height="700">
<br><br>
<i>IMAGE DESCRIPTION: {{ detail.image_description }}</i>
</center>
{% endif %}
<hr>
<br><br><br>
{{ detail.body|linebreaksbr }}
</p>
<hr class="solid">
<h2>COMMENTS ...</h2>Add One
{% for comment in post.comments.all %}
<strong>
{{ comment.name }}-{{ comment.date_added }}
</strong>
{{ comment.body }}
{% endfor %}
</article>
{% endblock %}
add_comments.html
{% extends 'base.html' %}
{% block content %}
<article>
{% if user.is_authenticated %}
<h1>CREATE NEW BLOG POST.</h1>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">ADD COMMENT</button>
<input type="hidden" name="next" value="{% url 'blog_detail' pk=post.pk %}"/>
</form>
{% else %}
<h2>Login HERE to add comments.</h2>
{% endif %}
</article>
{% endblock %}
in your template you use
{% for comment in post.comments.all %}
but in template context there is no post variable
you should use {% for comment in detail.comments.all %}
I have tried various patterns of solutions but for some reason they don't work. Below I attached the pieces of code that I think are contributing to the error. I have included the full view file that renders list.html
models.py
from django.db import models
from django.utils import timezone
# Create your models here.
class task(models.Model):
title = models.CharField(max_length = 40)
category = models.CharField(max_length = 20)
description = models.CharField(max_length = 100)
date = models.DateField(default = timezone.now)
finished = models.BooleanField(default = False)
def __str__(self):
return self.title
views.py
def main(request):
form = taskForm()
context = {
'doItems': task.objects.all(),
'form': form,
}
return render(request, 'todoList/list.html', context)
#require_POST
def addToDO(request):
form = taskForm(request.POST)
if form.is_valid():
items = task(title = request.POST['title'], category = request.POST['category'], description = request.POST['description'])
items.save()
return redirect('main')
def completedToDO(request, task_id):
items = task.objects.get(pk = task_id)
items.finished = True
items.save()
return redirect('main')
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.main, name = 'main'),
path('add', views.addToDO, name = 'add'),
path('finished/<task_id>', views.completedToDO, name = 'finished'),
]
list.html
<ul class="list-group">
{{ items.title }} <b> {{ items.category }} </b> <br> {{ items.description }} <br> <hr> {{ items.date }}</li>
</ul>
You need to pass value of tasks.id to the url. You can try like this(assuming item variable is an instance of Task class):
{{ items.title }} <b> {{ items.category }} </b> <br> {{ items.description }} <br> <hr> {{ items.date }}</li>
My question is about redirection again to a /topics/ page where all entries for topic are located. When I end an entry this code and reload tab than showing this error is occured as below:
Reverse for 'topic' with arguments '('',)' not found. 1 pattern(s) tried: ['topic/(?P[^/]+)$']
how can i solved this?
at views.py
from django.shortcuts import render, HttpResponse
from django.views.generic.base import View
from .models import author, catagory, article
# Create your views here.
class HomeView(View):
def get(self, request, *args, **kwargs):
post = article.objects.all()
context = {
"post":post
}
return render (request, 'index.html', context)
def getauthor(request, name):
return render (request, 'profile.html')
def getsingle(request, id):
return render (request, 'single.html')
def getTopic(request, name):
return render (request, 'category.html')
at urls.py
from django.urls import path
from .import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', views.HomeView.as_view(), name = 'home'),
#path('about/', views.AboutView.as_view(), name = 'about'),
path('author/<name>', views.getauthor, name = 'author'),
path('article/<int:id>', views.getsingle, name = 'single_post'),
path('topic/<name>/', views.getTopic, name = 'topic'),
]
urlpatterns+= static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
at index.html
{% extends "base.html" %}
{% load static %}
{% block title %} Welcome to my django templates {% endblock %}
{% block content %}
{% for p in post %}
<article class="col-lg-3 col-md-3 col-sm-3 col-xs-6 col-xxs-12 animate-box">
<figure>
<img src="{{ p.image.url }}" alt="Image" class="img-responsive">
</figure>
<span class="fh5co-meta">{{ p.category.name }}</span>
<h2 class="fh5co-article-title">{{ p.title }}</h2>
<span class="fh5co-meta fh5co-date">{{ p.posted_on }}</span>
</article>
{% endfor %}
{% endblock %}
Modles.py are
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class author(models.Model):
name = models.ForeignKey(User, on_delete = models.CASCADE, related_name='blog_posts')
details = models.TextField()
def __str__(self):
return self.name.username
class catagory(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class article(models.Model):
article_author = models.ForeignKey(author, on_delete = models.CASCADE, related_name='blog_posts')
title = models.CharField(max_length=200)
body = models.TextField()
image = models.FileField()
posted_on = models.DateTimeField (auto_now= False, auto_now_add= True)
updated_on = models.DateTimeField (auto_now= True, auto_now_add= False)
catagory = models.ForeignKey(catagory, on_delete = models.CASCADE)
def __str__(self):
return self.title
I have a little problem. I want to create something like a webpages directory. In my model I've create a class Kategorie, and class Firma. Class Kategoria creating main categories and subcategories. In class Firma I can define in witch category and subcategory the new record will be belong. My question is: How to display in html on main page main categories and little lower the subcategories like in this picture
Here is my code
models.py
from django.db import models
from django.contrib.auth.models import User
class Kategoria(models.Model):
name = models.CharField(max_length=250, verbose_name='Kategoria')
slug = models.SlugField(unique=True,verbose_name='Adres SEO')
parent = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.CASCADE)
class Meta:
unique_together = ('slug', 'parent',)
verbose_name = 'Kategoria'
verbose_name_plural = 'Kategorie'
def __str__(self):
full_path = [self.name]
k = self.parent
while k is not None:
full_path.append(k.name)
k = k.parent
return ' / '.join(full_path[::-1])
class Firma(models.Model):
user = models.ForeignKey(User, default=1, verbose_name='Użytkownik', on_delete=models.CASCADE)
title = models.CharField(max_length=250, verbose_name='Nazwa firmy')
slug = models.SlugField(unique=True, verbose_name='Adres SEO')
category = models.ForeignKey('Kategoria', null=True, blank=True, verbose_name='Kategoria', on_delete=models.CASCADE)
content = models.TextField(verbose_name='Opis')
draft = models.BooleanField(default=False, verbose_name='Szablon')
publish = models.DateField(auto_now=False, auto_now_add=False)
class Meta:
verbose_name='Firma'
verbose_name_plural='Firmy'
def __str__(self):
return self.title
views.py
from django.shortcuts import render, get_object_or_404
from .models import Kategoria, Firma
def widok_kategorii(request):
kategorie = Kategoria.objects.filter().order_by('name')
context = {'kategorie': kategorie}
return render(request, 'ogloszenia/index.html', context=context)
index.html
{% include 'ogloszenia/header.html' %}
Wyświetl kategorie<br>
{% for kategoria in kategorie %}
<b>{{kategoria.name}}<br></b>
{% endfor %}
{% include 'ogloszenia/footer.html' %}
So the problem is sub categories, right?
You can use inclusion_tag in your template as i mentioned here once:
Tree Structure (Foreign Keys to itself) and templates
If you need to render multiple level of sub categories then just do as i mentioned in the link.
But if you just need the first level, then it's pretty simple:
views.py:
Getting categories without any parent (line #2)
def widok_kategorii(request):
### Get the categories without any parent.
kategorie = Kategoria.objects.filter(parent=None).order_by('name')
context = {'kategorie': kategorie}
return render(request, 'ogloszenia/index.html', context=context)
Template:
{% include 'ogloszenia/header.html' %}
Wyświetl kategorie<br>
<ul>
{% for kategoria in kategorie %}
<li>
{{kategoria.name}}
{% if kategoria.children.count > 0 %}
<ul>
{% for sub in kategoria.children.all %}
<li>{{ sub.name }}</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% include 'ogloszenia/footer.html' %}
You can just design it to be look like the picture you posted but this is the way to achive the tree structure for such a design.
I've created a new form for comments the articles on a website. When I add the new comment from django admin everything works ok, but when I try to add the new comment directly from detail page nothings happen and I'am redirecting to the page with list of articles.
here are my files
models.py:
class Komentarz(models.Model):
post = models.ForeignKey(Wpisy, related_name="komentarze", verbose_name="Komentarze do artykułu", on_delete=models.CASCADE)
name = models.CharField(max_length=80, verbose_name="Imię")
email = models.EmailField(verbose_name="Email")
content = models.TextField(verbose_name="Treść komentarza")
created_date = models.DateTimeField(verbose_name="Utworzono", auto_now_add=True)
active = models.BooleanField(verbose_name="Aktywny?", default=True)
class Meta:
ordering = ('created_date',)
verbose_name="Komentarz"
verbose_name_plural="Komentarze"
def __str__(self):
return 'Komentarz dodany przez {} dla strony {}'.format(self.name, self.post)
vies.py with the function of details
from django.shortcuts import render, get_object_or_404
from .models import Wpisy, Komentarz
from .forms import KomentarzeForma
....
def detale_bajki(request, slug, ):
detale_bajki = get_object_or_404(Wpisy, slug=slug)
komentarze = detale_bajki.komentarze.filter(active=True)
if request.method == 'POST':
formularz_komentarza = KomentarzeForma(data=request.POST)
if formularz_komentarza.is_valid():
nowy_komentarz = formularz_komentarza.save(commit=False)
nowy_komentarz.detale_bajki = detale_bajki
nowy_komentarz.save()
else:
formularz_komentarza = KomentarzeForma()
return render(request, 'bajki/detale_bajki.html', {'detale_bajki': detale_bajki, 'komentarze': komentarze, 'formularz_komentarza': formularz_komentarza})
forms.py
from .models import Komentarz
from django import forms
class KomentarzeForma(forms.ModelForm):
class Meta:
model = Komentarz
fields = ('name', 'email', 'content')
and detail.html
...
{% with komentarze.count as total_komentarze %}
<h2>
{{ total_komentarze }} komentarz{{ total_komentarze|pluralize:"y" }}
</h2>
{% endwith %}
{% for komentarz in komentarze %}
Komentarz dodany przez <strong>{{komentarz.name}}</strong>
{{komentarz.created_date}}
<p>
{{ komentarz.content|linebreaks }}<br>
{% empty %}
<p>Nie dodano jeszcze żadnych komentarzy</p>
{% endfor %}
{% if nowy_komentarz %}
<h2>Twój komentarz został dodany</h2>
{% else %}
<h2>Dodaj nowy komentarz</h2>
<form action="." method="post">
{{formularz_komentarza.as_p}}
{% csrf_token %}
<p><input type="submit" value="Dodaj komentarz"></p>
</form>
{% endif %}
clas Wpisy in models.py
class Wpisy(models.Model):
title = models.CharField(max_length=400, verbose_name="Tytuł")
slug = models.SlugField(unique=True, max_length=400,verbose_name="Przyjazny adres url")
content = models.TextField()
status_audio = models.BooleanField(default=False, verbose_name="Czy dostępny będzie plik audio?")
audio_file = models.FileField(upload_to='uploads/',verbose_name="Plik audio")
created_date = models.DateTimeField(blank=True, null=True, verbose_name="Data utworzenia")
category = models.ForeignKey(Kategorie, verbose_name="Kategoria", on_delete=models.CASCADE)
class Meta:
verbose_name="Wpis"
verbose_name_plural="Wpisy"
def __str__(self):
return self.title
Your url pattern is
path('bajki/<slug>', views.detale_bajki, name='detale_bajki')
Note that it doesn't have a trailing slash. Your form's action is "."
<form action="." method="post">
That means you are submitting to /bajki/, which is the wrong URL.
You could fix this by adding a trailing slash to the url (which is common in Django URLs)
path('bajki/<slug>/', views.detale_bajki, name='detale_bajki')
Or you could change the form action to "" instead of ".". In the comments it looks like you fixed the issue by changing the form action to {{ detale_bajki.slug }}.
However these changes to the form action are fragile, and could break if you change your URL patterns again. The best approach is to use the {% url %} tag to reverse the correct URL.
<form action="{% url 'detale_bajki' detale_bajki.slug %}" method="post">
Try out:
nowy_komentarz.post = detale_bajki
...
return render(request, 'html page', {'key': 'what you want to return to your context'}) # don't fornget to add some return to your view.