Exception Type: NoReverseMatch - Django - html

after researching for hours I cannot get rid of this error, I hope someone can help me.
Models:
class Puja(models.Model):
seller = models.OneToOneField(Seller, on_delete=models.CASCADE)
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True,null=True)
title = models.CharField(max_length=100)
video = models.FileField(blank=True)
photo = models.ImageField(blank=True)
published_date = models.DateTimeField("Published: ",default=timezone.now())
bidding_end = models.DateTimeField()
starting_price = models.IntegerField(default=1)
#slug = models.SlugField(null=True)
def __str__(self):
return str(self.title)
#def get_absolute_url(self):
# return reverse('bidding_list_detail', args=[str(self.id)])
#slug time
def get_absolute_url(self):
return reverse('bidding_list_detail',args={'id': self.id})
Views:
class bidding_list(ListView):
model = Puja
template_name = 'bidding_templates/bidding_list.html'
"""return render(request= request,
template_name='bidding_templates/bidding_list.html',
context = {"Pujas": Puja.objects.all})"""
class bidding_list_detail(DetailView):
model = Puja
template_name = 'bidding_templates/bidding_list_detail.html'
urls:
path('admin/', admin.site.urls),
path("bidding_list/", bidding_list.as_view(), name="bidding_list"),
path('<int:pk>', bidding_list_detail.as_view(), name='bidding_list_detail'),
admin:
class PujaAdmin(admin.ModelAdmin):
list_display = ('seller','title','video','photo','published_date','bidding_end','starting_price')
admin.site.register(Puja,PujaAdmin)
template 1:
{% extends 'header.html' %}
{% block content %}
<h1>Pujas</h1>
{% for Puja in object_list %} <!--object_list-->
<ul>
<li> {{ Puja.title }} </li>
</ul>
{% endfor %}
{% endblock %}
template 2:
{% extends 'header.html' %}
{% block content %}
<div>
<h2>{{ object.title }}</h2>
<p>{{ object.seller }}</p>
</div>
{% endblock %}
Note that, whenever I remove <a href="{{ Puja.get_absolute_url }}"> from the first template, the objects "puja" in the model get properly displayed on the template, but I cannot access them. They normally exist on the admin panel, but not displayed on the website directly.
Thank you very much on advance and stay healthy.
edit 1: Here is the urls.py directly from the app created by django. To be more specific, I created after the project a new app called "main" in which I programmed all the project, including all the code on this question except the edit.
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
#from django.config import settings
#from django.config.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls')),
#path('', include('model.urls')),
#path('', include('blog.urls')),
#path('', include('photo.urls')),
#path('', include('video.urls')),
] # +static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

I guess the problem is this line - return reverse('bidding_list_detail',args={'id': self.id}), you are passing id as a string but trying to match with int in url.Try following return reverse ('bidding_list_detail',args=[self.id])

Related

Django HTML button on-click invoke backend function

im trying to add to my html a button that appears only on certain events, that works for me but i want to add a onclick script/function that will invoke a backend view.py function that deletes the specific room on click, the room model is : owner(fk), name, slug.
and the user model is : username password1 password2.
i just need to know how to invoke an onclick event that will call the backend function in my views.
rooms.html
{% extends 'core/base.html' %}
{% block title %} Rooms | {% endblock %}
{% block content %}
<div class="main">
<h1>Rooms</h1>
</div>
<div class="rooms-container">
{% for room in rooms %}
<div class="room">
<div class="room-info">
<h1 class="room-title">{{ room.name }}</h1>
Join Room
{% if request.user == room.owner %}
<button class="room-delete" id="roomDelete">Delete Room</button>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block scripts %}
<!-- todo: add delete room button functionality. -->
{% endblock %} ```
views.py
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render
from django.contrib import messages
from .models import Room, Message
#login_required
def rooms(request):
if request.method == 'POST':
room_owner = request.user
room_name = request.POST['room-name']
if not Room.objects.filter(slug = room_name).exists():
if room_name == '' or room_name.isspace() or room_name.startswith(' '):
messages.info(request, 'Invalid room name, spaces-only or string that starts with spaces is invalid.')
else:
new_room = Room(owner = room_owner,name = room_name,slug = room_name)
new_room.save()
else:
messages.info(request, 'That room already exists!, try a different name.')
rooms = Room.objects.all()
return render(request, 'room/rooms.html', {'rooms': rooms})
#login_required
def room(request, slug):
room = Room.objects.get(slug=slug)
messages = Message.objects.filter(room=room)[0:25]
return render(request, 'room/room.html', {'room': room, 'messages': messages})
#csrf_exempt
def delete_room(request): ## <<------ invoke this from html call.
print("hey")
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.rooms, name='rooms'),
path('<slug:slug>/', views.room, name='room'),
path('', views.delete_room, name='delete_room'),
]
now i have more 2 urls.py, the project has 3 folders, 1 main (livechatapp) with settings and all, one for core htmls (core) and one for rooms html (room)
core/urls
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
path('', views.frontpage, name='frontpage'),
path('signup/', views.signup, name='signup'),
path('login/', auth_views.LoginView.as_view(template_name='core/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
and finally
livechatapp/urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('core.urls')),
path('rooms/', include('room.urls')),
path('admin/', admin.site.urls),
]
and this is the projects overview folders and files :
this is the project
IF you want do it in standard html:
% extends 'core/base.html' %}
{% block title %} Rooms | {% endblock %}
{% block content %}
<div class="main">
<h1>Rooms</h1>
</div>
<div class="rooms-container">
{% for room in rooms %}
<div class="room">
<div class="room-info">
<h1 class="room-title">{{ room.name }}</h1>
Join Room
{% if request.user == room.owner %}
<form method="POST" action="{% url 'delete_room' room.slug %}>
<button type="submit" class="room-delete">Delete Room</button></form>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block scripts %}
<!-- todo: add delete room button functionality. -->
{% endblock %} ```
urls:
urlpatterns = [
path('', views.rooms, name='rooms'),
path('<slug:slug>/', views.room, name='room'),
path('delete/<slug:slug>/', views.delete_room, name='delete_room'),
]
views:
#csrf_exempt
def delete_room(request,slug):
if request.method == 'POST':
try:
room = Room.objects.get(slug=slug, owner=request.user)
room.delete()
except ObjectDoesNotExist:
print('there is no room with this slug or you are not owner')
return redirect('rooms')
i advice to use csrf. allways try to use POST when manipulatind data in db.
If you want to work it without redirect you need to think of ajax call or maby htmx

Django model data not appearing

My model data for my website wont appear on new page when using slug and I am unsure as to why this is happening as I managed to get it to work with the previous page of the website but when I try to call it on my html page nothing will load now and I use the slug in the view to access the page.
Models.py
class Parasite(models.Model):
name = models.CharField(max_length=128, unique=True)
slug = models.SlugField(max_length=100, unique=True)
description = models.TextField(max_length=100000)
image = models.ImageField(upload_to='parasite_images', default='default/default.jpg', blank=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Parasite, self).save(*args, **kwargs)
def __str__(self):
return self.name
views.py
def view_parasite(request,parasite_name_slug):
context_dict = {}
try:
parasite = Parasite.objects.get(slug=parasite_name_slug)
context_dict['parasites'] = parasite
except Parasite.DoesNotExist:
context_dict['parasites'] = None
return render(request, 'parasites_app/viewpara.html', context = context_dict)
viewpara.html
{% extends 'parasites_app/base.html' %}
{% load static %}
{% block content_block %}
{% for p in parasite %}
<h3>{{p.name}}</h3>
{% endfor %}
{% endblock %}
urls.py
urlpatterns = [
path('login/', views.user_login, name='login'),
path('logout/', views.user_logout, name='logout'),
path('admin/', admin.site.urls),
path('', views.public, name='public'),
path('public/', views.public, name='public'),
path('private/', views.logged_in_content, name='private'),
path('public/<slug:parasite_name_slug>/',views.view_parasite, name='view_parasite'),
path('<slug:post_name_slug>/', views.show_post, name='show_post'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
First mistake - you are getting one Parasite object (cause you use method get) and you call it with plural name 'parasites':
parasite = Parasite.objects.get(slug=parasite_name_slug)
context_dict['parasites'] = parasite
Second mistake - when you want to show it in template, you call for single parasite, but you decided to name the key parasites.
{% for p in parasite %}
Third mistake - don't use for loop for one object, just call it.
Answer:
views.py
parasite = Parasite.objects.get(slug=parasite_name_slug)
context_dict['parasite'] = parasite
viewpara.html
{% block content_block %}
{{ parasite.name }}
{% endblock %}

How can I display all the users on my html page?

This piece of code gets me the required output in my python terminal
views.py
from django.contrib.auth.models import User
userList =User.objects.all()
print(userList)
outputs this in the terminal
<QuerySet [<User: brad>, <User: john>]>
I know I have to iterate through the QuerySet but I am not able to link this view to my main page.
So how can I get this on my main HTML page?
In your views.py create view as
from django.views.generic.list import ListView
from django.contrib.auth.models import User
class UserListView(ListView):
model = User
template_name = 'your_template_name.html'
Then in your urls.py
from django.urls import path
from yourapp.views import UserListView
urlpatterns = [
path('userlists', UserListView.as_view(), name='user-list'),
]
Then in your html loop through object_list as
<h1>User List</h1>
<ul>
{% for user in object_list %}
<li>{{ user.username }}</li>
{% empty %}
<li>No users yet.</li>
{% endfor %}
</ul>
Here is pseudo code you can try,
from django.contrib.auth.models import User
from django.shortcuts import render
def index(request):
userList =User.objects.all()
return render(request, 'users.html', {'users': userList})
And users.html like,
<h1>USERS</h1>
<ul>
{% for user in users %}
<li>{{ user }}</li>
{% endfor %}
</ul>
urls.py is like,
from django.contrib import admin
from django.urls import path
from app1.views import *
urlpatterns = [
path('', index),
path('admin/', admin.site.urls),
]

I am not getting the value from the database

I am using MVT in django. I am using generic CBV (listview, detailview). here are my codes
Here is model.py
from django.db import models
class Singers(models.Model):
name= models.CharField(max_length=256)
age= models.IntegerField()
gender= models.CharField(max_length=10)
class Albums(models.Model):
name= models.CharField(max_length=256)
singer=models.ForeignKey(Singers, on_delete=models.CASCADE)
view.py
from django.views import generic
from core.models import Albums, Singers
#in generic view instead of functions, we use classes
class AlbumView(generic.ListView):
model = Albums
template_name = 'index.html'
paginate_by = 10
def get_queryset(self):
return Albums.objects.all()
class DetailView(generic.DetailView):
model = Albums
template_name = 'detailview.html'
Here are urls.py
from django.urls import path
from core.views import AlbumView, DetailView
urlpatterns = [
path('album/', AlbumView.as_view()),
path('album/detail/<pk>/', DetailView.as_view())
]
Here is index.html
{% block content %}
<h2>Albums</h2>
<ul>
{% for albums in object_list %}
<li>{{ albums.name }}</li>
{% endfor %}
</ul>
{% endblock %}
here is detailview.html
{% block content %}
<h1>name: {{Albums.name}}</h1>
<p><strong>Singer: {{Albums.Singer}}</strong></p>
{% endblock %}
The detail view is not working fine. It is not fetching the respective name of the album and singer details.
Suggest me what should i do?
Try this
{% block content %}
<h1>name: {{object.name}}</h1>
<p><strong>Singer: {{object.singer.name}}</strong></p>
{% endblock %}
class DetailView(generic.DetailView):
model = Albums
template_name = 'detailview.html'
This is not working you have to get first context like this
def get_context_data(self, **kwargs):
// Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
// Add in a QuerySet of all the books
context['Album_list'] = Albums.objects.all()
return context
And you can do as well
context_object_name = 'publisher'
queryset = Publisher.objects.all()

django adds %EF%BB%BF at the end of my urls

I am working on a blog django app.
I have list of posts and a post detail pages.
when I click on a post title in the list should takes to the post detail page.
views.py
from django.shortcuts import render, get_list_or_404
from .models import Post
def list_of_post(request):
post = Post.objects.all()
template = 'blog/post/list_of_post.html'
context = {'post': post}
return render(request, template, context)
def post_detail(request, slug):
post = get_list_or_404(Post, slug=slug)
template = 'blog/post/post_detail.html'
context = {'post': post}
return render(request, template, context)
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.list_of_post, name='list_of_post'),
url(r'^(?P<slug>[-\w]+)/$', views.post_detail, name='post_detail')
]
models.py
from django.db import models
from django.utils import timezone
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published')
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250)
content = models.TextField()
seo_title = models.CharField(max_length=250)
seo_description = models.CharField(max_length=160)
author = models.ForeignKey(User, related_name='blog_posts')
published = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=9, choices=STATUS_CHOICES, default='draft')
def get_absolute_url(self):
return reverse('blog:post_detail', args=[self.slug])
def __str__(self):
return self.title
list_of_post.html
{% extends 'blog/base.html' %}
{% block title %}List of blog post{% endblock %}
{% block content %}
{% for posts in post %}
<h2>{{ posts.title }}</h2>
<p>Written by {{ posts.author }} on {{ posts.published }}</p>
<hr>
{{ posts.content|truncatewords:40|linebreaks }}
{% endfor %}
{% endblock %}
for some reason the url doesn't work. instead shows 404 that looks like this :
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/practice-title/%EF%BB%BF
Using the URLconf defined in cms.urls, Django tried these URL patterns,in this order:
^admin/
^blog/ ^$ [name='list_of_post']
^blog/ ^(?P<slug>[-\w]+)/$ [name='post_detail']
The current URL, blog/practice-title/, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
and ideas?