Django no reverse match for view details - django

im stuck on show details for object, no matter i do (following all guides on internet )
still getting reverse not match error
views.py
def val_details(request, id):
val = Validator.objects.get(id=id)
print(f'vali: {val}')
context = dict(val=val)
return render(request, 'users/val_details.html', context)
print(f'vali: {val}') printing vali: Validator object (14)
html
<button class="btn btn-warning " href="{% url 'val-details' val.id %}">detals</button>
urls.py
path('dashboard/validator/<int:id>/', user_views.val_details, name='val-details'),
models.py
class Validator(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=200, blank=True, null=True)
address = models.CharField(max_length=200, blank=True, null=True)
owner = models.CharField(max_length=250, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
def __int__(self):
return self.id
error
django.urls.exceptions.NoReverseMatch: Reverse for 'val-details' with arguments '('',)' not found. 1 pattern(s) tried: ['users/validator/(?P<id>[0-9]+)/$']
profile view
def profile(request):
valid = Validator.objects.filter(user=request.user)
valid_count = valid.count()
context = {
'valid': valid,
'valid_count': valid_count,
}
return render(request, 'users/profile.html', context)
and urls.py
from django.urls import path
from users import views as user_views
urlpatterns = [
path('dashboard/', user_views.profile, name='dashboard'),
path('dashboard/validator/<int:id>/', user_views.val_details, name='val-details'),
]

this is the typical error message if in your
<button class="btn btn-warning " href="{% url 'val-details' val.id %}">detals</button>
val.id is either NULL or empty.
Please check where you assign it.

Related

How to get the previous and next related post in django?

views.py
def post_details(request,pk):
post = Post.objects.get(id=pk)
# next_post = Post.objects.filter(id=pk)
context={'post':post,'next':next_post}
return render(request, 'blog/post_detail.html', context)
blog-detail
<div class="s-content__pagenav group">
<div class="prev-nav">
<a href="#" rel="prev">
<span>Previous</span>
Tips on Minimalist Design
</a>
</div>
<div class="next-nav">
<a href="#" rel="next">
<span>Next</span>
Less Is More
</a>
</div>
</div>
models
# this is my model
class User(AbstractUser):
# pass
name = models.CharField(max_length=200)
bio = models.TextField(null=True)
email = models.EmailField(unique=True, null=True)
avatar = models.ImageField( null=True, upload_to='blog_media', default="images/avatar.svg")
facebook = models.URLField(blank=True, null=True)
twitter = models.URLField(blank=True, null=True)
dribbble = models.URLField(blank=True, null=True)
instagram = models.URLField(blank=True, null=True)
class Category(models.Model):
name = models.CharField(max_length=20)
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ManyToManyField(Category)
title = models.CharField(max_length=200, blank=False);
description = models.TextField(null=True,blank=True)
image = models.ImageField(upload_to='blog_media')
url = models.URLField(null=True, blank=True)
body = HTMLField()
created = models.DateTimeField(auto_now=True)
updated = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Based on your comments, I'm assuming that you would like to get two related posts that have the same category as the current post.
If I'm correct, then one method you could use is to filter the queryset for the same category belonging to the current post then you could choose the next and previous posts of the current post from the retrieved queryset. For example:
def post_details(request, pk):
current_post = Post.objects.get(pk=pk) # retrieving the current post...
# filtering for related posts only by using the category of the current post
# using -> category_in=post.category.all() since it's a ManyToMany field
related_posts = Post.objects.filter(category_in=current_post.category.all())
# next -> get posts with id greater than the current post id, then get the first instance 'next post'
# previous -> get posts with id less than the current post id, then get the first instance 'previous post'
context = {
'post': current_post,
'next': related_posts.filter(id__gt=current_post.id).order_by('id').first(),
'previous': related_posts.filter(id__lt=current_post.id).order_by('-id').first()
}
return render(request, 'blog/post_detail.html', context)
Ideally, that should work.
A quick recommendation here as well... Instead of using Post.objects.get(pk=pk), I'd suggest using get_object_or_404() as this will handle any potential error that Post.objects.get(pk=pk) will throw. So a small update...
from django.shortcuts import get_object_or_404
def post_details(request, pk):
current_post = get_object_or_404(Post, pk=pk) # retrieving the current post...
# the rest of the code follows...

Trying to delete a comment from a post in django

I am currently trying to delete a comment from my database via a button in django template.
Model looks like this
from django.db import models
from django.contrib.auth.models import User
from cloudinary.models import CloudinaryField
from profiles.models import UserProfile
class Post(models.Model):
user_profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, related_name='user_posts')
title = models.CharField(max_length=220, unique=True)
location = models.CharField(max_length=220)
rating = models.DecimalField(
max_digits=6, decimal_places=2)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="activity_post")
updated_on = models.DateTimeField(auto_now=True)
description = models.TextField()
featured_image = CloudinaryField('image', blank=False)
created_on = models.DateTimeField(auto_now_add=True)
likes = models.ManyToManyField(User, related_name='activity_likes', blank=True)
like_count = models.BigIntegerField(default='0')
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def number_of_likes(self):
return self.likes.count()
def liked_by_user(self):
return self.likes.values_list('id', flat=True)
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name="user_comment")
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['created_on']
def __str__(self):
return f"Comment {self.body} by {self.name}"
Delete function
def delete_comment(request, post_id):
users_comment = get_object_or_404(Comment, post=post_id)
users_comment.delete()
return redirect(reverse('activity'))
URLS
from . import views
from django.urls import path
urlpatterns = [
path('like/', views.like, name='like'),
path("add/", views.add_post, name="add_post"),
path('edit/<int:post_id>/', views.edit_post, name='edit_post'),
path('delete/<int:post_id>/', views.delete_post, name='delete_post'),
path('edit_comment/<int:id>/', views.edit_comment, name='edit_comment'),
path('delete_comment/<int:post_id>/', views.delete_comment, name='delete_comment'),
path("activity/", views.PostList.as_view(), name="activity"),
path('comment/<int:post_id>/', views.Comment.as_view(), name='comment'),
path('searched_posts/', views.search_posts, name='searched_posts'),
path('post/<int:post_id>/', views.post_detail, name='post_detail')
]
here is the comment part that is showing the button.
{%if comments %}
{% for comment in comments %}
{% if comment.user == request.user %}
{{comment.body}} :comment
{{comment.id}} id
<a class="btn tbn-success" href="{% url 'edit_comment' comment.id %}" aria-label="edit button">Edit</a>
<button class="btn btn-warning">Delete</button>
{% endif %}
{% endfor%}
{% endif%}
When I click delete i get an error
Error
Any help would be greatly appreciated, I have tried a ton of different ways from online but nothing seems to work. can anyone point me in the right direction
The first thing I can see is that your delete function uses post = post_id.
Every comment on a particular post will share that post foreign key, so if there is more than one comment on a post, you can't use get_or_404() - it's limited to returning 1 item.
The URL you create for your button is using comment.id so it makes sense to use that instead - this will make it easier to see what's happening.
urls.py
path('delete_comment/<int:comment_id>/', views.delete_comment, name='delete_comment'),
views.py
def delete_comment(request, comment_id):
users_comment = get_object_or_404(Comment, pk=comment_id)
users_comment.delete()
return redirect(reverse('activity'))

tried deleted data but failed to delete from django database

I have created models.py, views.py, and urls.py and later on accordingly updated data.html file but when I click on the delete button it gives me an error. so the error file also attached for reference. Help appreciated and waiting for resolution.
error file
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/delete/
Using the URLconf defined in student.urls, Django tried these URL patterns, in this order:
admin/
[name='index']
export/ [name='export']
export-pdf [name='export-pdf']
register/ [name='register']
login/ [name='login']
home/ [name='home']
logout/ [name='logout']
upload/ [name='upload']
result/ [name='result']
dashbord/ [name='dashbord']
data/ [name='data']
delete/<int:id>
^static/(?P<path>.*)$
The current path, delete/, 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.
urls.py
path('data/', views.data, name='data'),
path('delete/<int:id>', views.delete),
data.html
<a href="/edit/{{ student.id }}" class="btn btn-success"><span>Edit</span></a
Delete
views.py
def data(request):
data1 = Contact.objects.all()
# myFilter = OrderFilter()
dict = {
"data1":data1
}
return render(request, 'data.html', context=dict)
# Delete Data
def delete(request):
data1 = Contact.objects.all(id=id)
data1.delete()
return redirect("/data")
model.py
from django.db import models
from django.db.models.fields import CharField
from django.contrib import admin
# Create your models here.
class Contact(models.Model):
name = models.CharField(max_length=50, default="")
contact = models.CharField(max_length=50, default='')
address = models.TextField(max_length=50, default='')
program = models.CharField(max_length=50, default='')
email = models.CharField(max_length=50, primary_key=True, null=False, unique=True)
w3review = models.TextField(max_length=60, default="")
def __str__(self):
return self.name
class Cv(models.Model):
filename = models.CharField(max_length=20)
upload = models.FileField(upload_to='cv')
def __str__(self):
return self.filename
I think you didnt specify the id number after
http://127.0.0.1/delete:8000/--id-here--
I think you need to use get() method instead of all() method. You code should be something like this:
def delete(self, request, id):
data1 = Contact.objects.get(id=id)
data1.delete()
return redirect("/data")
And you must specify the id number according to #Ariel's Answer.

Django 3.0: Getting error for get_absolute_url

I am getting this error:
TypeError at /product/177042279214449276022367789942330057699/
product() got an unexpected keyword argument 'id'
I am trying to generate detail page of product (book is product).
urls.py
app_name = 'bookrepo'
urlpatterns = [
path('',views.home,name='home'),
path('product/',views.product,name='product'),
path('product/<id>/', views.product, name='product_detail'),
]
template where I am using get_absoulte_url
<a href="{{ item.get_absolute_url }}" class="btn btn-sm my-btn detail-btn">
<span><i class="fa fa-info-circle"></i></span> View Details
</a>
views.py
def product(request):
return render(request, 'bookrepo/product.html')
models.py
class Book(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField('Title', max_length=255)
authors = models.ManyToManyField(Author, related_name='books_written')
publisher = models.ForeignKey(Publisher, on_delete=models.DO_NOTHING, related_name='books_published')
price = models.DecimalField('Price', decimal_places=2, max_digits=10)
description = models.TextField('Description')
upload_timestamp = models.DateTimeField('Uploading DateTime', auto_now_add=True)
categories = models.ManyToManyField(Category, related_name='book_category')
def get_absolute_url(self):
return "/product/%i/" % self.id
I might be completely wrong with respect to my view and urls. I want to display book details after button in template gets clicked.
Change views.py
def product(request, id=None):
return render(request, 'bookrepo/product.html')

Django: NoReverseMatch at /courses/2/

Getting this error:
Reverse for 'step' with arguments '()' and keyword arguments '{'course_pk': 2, 'step_pk': ''}' not found. 1 pattern(s) tried: ['courses/(?P<course_pk>\\d+)/(?P<step_pk>\\d+)/']
/urls.py
...
url(r'^courses/', include('courses.urls', namespace='courses')),
...
/courses/urls.py
...
url(r'(?P<course_pk>\d+)/(?P<step_pk>\d+)/$', views.step_detail, name='step'),
...
Error during template rendering:
The html line generating the error is:
...
{{ step.title }}
...
courses/models.py
class Course(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=255)
description = models.TextField()
def __str__(self):
return self.title
class Step(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
content = models.TextField(blank=True, default='')
order = models.IntegerField(default=0)
course = models.ForeignKey(Course)
class Meta:
ordering = ['order', ]
def __str__(self):
return self.title
courses/views.py
def course_detail(request, pk):
# course = Course.objects.get(pk=pk)
course = get_object_or_404(Course, pk=pk)
return render(request, "courses/course_detail.html", {"course": course})
def step_detail(request, course_pk, step_pk):
step = get_object_or_404(Step, course_id=course_pk, pk=step_pk)
return render(request, "courses/step_detail.html", {"step": step})
I can't seem to understand where the problem is as I'm currently new to Django. Much help would be appreciated.
you need
{% url 'courses:step' course_pk=step.course.pk step_pk=step.pk %}
step.pk instead of step_pk which doesnot exist in your context
In the line
<a href=" {% url 'courses:step' course_pk=step.course.pk step_pk=step_pk %} ">
Here step_pk = step_pk is not working. Step_pk is not defined because you did not return any information about step_pk in def course_detail at this line:
return render(request, "courses/course_detail.html", {"course": course})
pass step inside return and use step_pk = step.pk
Please check it. Thanks.