Django can't find my DetailView with Primary Key - django

I'm trying to make a simple page with Django where posts are being displayed using primary keys. However, the DetailView page with my posts can't be displayed.
This is my model:
class Post(models.Model):
author = models.CharField(max_length=100)
title = models.CharField(max_length=100)
posted_date = timezone.now()
text = models.TextField()
def get_absolute_url(self):
return reverse("postdetail", kwargs={"pk": self.pk})
def __str__(self):
return self.title
and here is my url pattern list:
urlpatterns = [
url(r'^posts/(?P<pk>\d+)$', views.PostDetail.as_view(), name="postdetail"),
url(r'^$', views.index, name="index"),
url(r'^thanks/$', views.Thanks.as_view(), name="thanks"),
url(r'^postlist/$', views.PostList.as_view(), name="postlist"),
]
The template is in my templates folder under the name "post_detail.html".
Here is the DetailView:
class PostDetail(DetailView):
context_object_name = 'post_details'
model = Post
I can't see where I might have a mistake. I have a ListView that shows my posts including the primary keys. But when I try to open the URL http://127.0.0.1:8000/posts/1/
I get:
`Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/posts/1/
Using the URLconf defined in myproj.urls, Django tried these URL patterns, in this order:
admin/
^posts/(?P<pk>\d+)$ [name='postdetail']
^$ [name='index']
^thanks/$ [name='thanks']
^postlist/$ [name='postlist']
The current path, posts/1/, didn’t match any of these.
Do you have a clue why the URL cannot be found? Thank you very much.`

Instead of url() use path()
from django.urls import path
urlpatterns = [
path('', views.index, name = "index"),
path('posts/<int:pk>', views.PostDetail.as_view(), name = "postdetail"),
path('postlist/', views.PostList.as_view(), name="postlist"),
path('thanks', views.Thanks.as_view(), name = "thanks"),
]
NB: url() been deprecated since version 3.1 and removed in 4.0

You are trying to access : http://127.0.0.1:8000/posts/1/ when you define the following http://127.0.0.1:8000/posts/1 without the backlash.
Try : http://127.0.0.1:8000/posts/1

First Things Is Your Views. You can send your database data with return it to the HTML.
views.py
def post(request,id):
post = Post.objects.get(id=id)
return render(request,'blog/index.html',{'post':post})
and before sending data into the HTML you should get the post id in your urls.py
urls.py
path('post/<int:id>', views.post, name='post.blog')
then in your HTML you can handle that data comes from your views.py
index.html
<div class="post-content content">{{ post.body|safe }}</div>

Related

Reverse for 'django_summernote-upload_attachment' not found. 'django_summernote-upload_attachment' is not a valid view function or pattern name

I keep having this error when I try to add a post.
It says,
"Reverse for 'django_summernote-upload_attachment' not found. 'django_summernote-upload_attachment' is not a valid view function or pattern name."
I know this is not a matter of adding "path('summernote/', include('django_summernote.urls')" because I've already done that.
models.py
from django.db import models
from django.contrib.auth.models import User
from django_summernote.widgets import SummernoteWidget, SummernoteInplaceWidget
CATEGORY = (
("Beginner", "Beginner"),
("Intermediate", "Intermediate"),
("Advanced", "Advanced"),
)
class Post(models.Model):
title = models.CharField(max_length=300, unique=True)
slug = models.SlugField(max_length=300, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='course_posts')
content = models.TextField()
# content = models.CharField(widget=SummernoteWidget())
category = models.CharField(max_length=25, choices=CATEGORY, default="Beginner")
created_at = models.DateField(auto_now_add=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return self.title
urls.py
from . import views
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
app_name = 'course_app'
urlpatterns = [
path('course/', views.PostList.as_view(), name='course'),
path('course/<slug:slug>/', views.PostDetail.as_view(), name='course_posts'),
path('summernote/', include('django_summernote.urls')),
path('editor/', include('django_summernote.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
from django.shortcuts import render
from django.views import generic
from .models import Post
class PostList(generic.ListView):
"""
Return all posts that are with status 1 (published) and order from the latest one.
"""
queryset = Post.objects.order_by('-created_at')
template_name = 'course.html'
class PostDetail(generic.DetailView):
model = Post
template_name = 'course_post.html'
def courses(request):
return render(request, 'course.html', {'navbar': 'courses'})
I tried adding a jpg file as a attachment, and that works. It's just the "add post" function that I have an error with.
Please help!
This is how my URLs look like and it is working well, but before I was getting the same error and I fixed it by adding those two paths summernote and editor
urlpatterns = [
path('', RedirectView.as_view(url='admin/login/', permanent=False), name='/'),
path('admin/', admin.site.urls),
path('summernote/', include('django_summernote.urls')),
path('editor/', include('django_summernote.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
It seems that the pattern with name 'django_summernote-upload_attachment' is not present in your urlpatterns variable. Looking at the urls.py file from this package (see https://github.com/summernote/django-summernote/blob/main/django_summernote/urls.py) we can see that the corresponding pattern is added only if the 'disable_attachment' key value for the config is False.
Check your settings.py file and look for the SUMMERNOTE_CONFIG variable. There you should see the 'disable_attachment' key. Make sure that its value is set to False (see https://github.com/summernote/django-summernote#options). Otherwise, the urlpattern that Django is trying to reach won't be registered and you will get the error that you posted.
As a side note, take care with the urls.py file and the patterns included there because you are including the same set of patterns in two different endpoints:
path('summernote/', include('django_summernote.urls')), # using include('django_summernote.urls')
path('editor/', include('django_summernote.urls')) # using include('django_summernote.urls') once again
This can cause redirection problems if the patterns included have the same naming. Removing one of these two patterns will do the job, just take it into account across your other files!

Django bug report, different foreign key as URL parameter will cause detailed view not executing

Edit3:
the culprit is re_path, not foreign key
Original:
This bug is so subtle I couldn't really find a niche way to describe it, For example I have two apps, News and Blogs
In blogs.py model I have something like this:
class BlogType(models.Model):
blog_type = CharField(max_length=20)
def __str__(self):
return self.blog_type
class Blogs(models.Model):
title = models.CharField(max_length=20)
blog_author = models.ForeignKey(User, on_delete=models.CASCADE)
blog_type = models.ForeignKey(BlogType, on_delete=models.DO_NOTHING)
here a blog_type is a foreignkey defined inside the same models.py
In blogs url.py
from django.urls import path, re_path
from . import views
from .views import blogspage
urlpatterns = [
path('', views.blogs, name='blogs'),
re_path(r'(?P<blog_type>[\w-]+)/(?P<pk>[0-9]+)$', blogspage.as_view(), name='blogspage'),
]
Here using the forignkey as a url parameter
And in blogs views.py
class blogspage(DetailView):
model=Blogs
template_name='blogs/blogspage.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
print('Print the object if this is executed', self.get_object())
In Django template you would pass something like:
<div>{{b.title}}</div>
Now the news model.py you have:
class NewsType(models.Model):
news_type = CharField(max_length=20)
def __str__(self):
return self.news_type
class News(models.Model):
title = models.CharField(max_length=20)
news_author = models.ForeignKey(User, on_delete=models.CASCADE)
news_type = models.ForeignKey(NewsType, on_delete=models.DO_NOTHING)
The news views, news urls, news templates, are the exactly the same as blog except the name and template name, basically replacing every single "blogs" to "news"
Then here is where the bug would occur, Only one detailed view will ever execute, for example when someone clicks "{%url "blogspage" blog.blog_type blog.id%}" It will go to url blog/blog_type/pk but the content will be news, However, If <foreignkey> blog_type is removed from url parameter, Only then the detailed view of blog will execute and the correct blog content will be rendered.
news url.py:
urlpatterns = [
path('', views.news, name='news'),
re_path(r'(?P<news_type>[\w-]+)/(?P<pk>[0-9]+)$', newspage.as_view(), name='newspage'),
]
root url.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('news.urls')),
path('blogs/',include('blogs.urls')),
] # path('news/', include('news.urls')), will not conflit
# switch the position between blogs.urls and news.urls also no conflit
Edit: www.example.com/blogs/blog_type/1 and www.example.com/news/news_type/1 will not conflit but www.example.com/blogs/blog_type/1 and www.example.com/news_type/1 will
Edit2: Because "" and "/blogs" bugged I automatically assume "/blogs" and "/news" will also bug, But the bug only exist between "" and "/blogs"
It looks like an issue with Django path and re_path method, where as per your scenario the re_path for both blogs and news URLs for newspage and blogpage are matching and django is not able to resolve the correct URL and redirect on the first matching URL.

URL parameter in Django RESTApi

Thank you in advance,
I'm new to Django REST Framework.
when i use get() method with id parameter, it is working fine
Below is url.py
urlpatterns = [
path('admin/', admin.site.urls),
url(r'api/userList/$', UserList.as_view(), name="userList"),
url(r'^api/userList/(?P<id>\d+)/$', UserDetails.as_view(), name="userDetails")
]
Below is api.py:
class UserDetails(APIView):
def get(self, request, id):
model = Users.objects.get(id=id)
serializer = UsersSerializers(model)
return Response(serializer.data)
above code is fine
When i try to get user details by using emailID, i'm not able to get the details, showing below error:
Using the URLconf defined in myProject.urls, Django tried these URL patterns, in this order:
1. admin/
2. api/userList/$ [name='userList']
3. ^api/userList/(?P<emailID>\d+)/$ [name='userDetails']
The current path, api/userList/sannila1527#gmail.com/, didn't match any of these.
Below is api.py:
class UserDetails(APIView):
def get(self, request, emailID):
model = Users.objects.get(emailID=emailID)
serializer = UsersSerializers(model)
return Response(serializer.data)
Can you please help me on this.
Try changing your url.py to
urlpatterns = [
path('admin/', admin.site.urls),
url(r'api/userList/$', UserList.as_view(), name="userList"),
url(r'^api/userList/(?P<emailID>\w+|[\w.%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', UserDetails.as_view(), name="userDetails")
]
Try changing this, urls.py
url(r'^api/userList/(?P<id>\d+)/$', UserDetails.as_view(), name="userDetails")
to,
url(r'^api/userList/(?P<emailID>\d+)/$', UserDetails.as_view(), name="userDetails")
Note: This can make problems at other places, you can fix them by replacing id with emailID elsewhere.

No Reverse Match Why?

I get this error whenever i try to open my localhost:8000 which happens to be the homepage of the app i'm working on.
NoReverseMatch at /
Reverse for 'category_detail' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['category/(?P<slug>[\\-\\w]+)/$']
Below are the {% url %} use in template, my models.py, my urls.py and views.py
What is happening? What am I doing wrong?
#in Template.
View
#my urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^$', views.home.as_view(), name='home'),
url(r'^categories/$', views.MyCategory.as_view(), name='all_categories'),
url(r'^category/(?P<slug>[-\w]+)/$', views.CategoryDetail.as_view(), name='category_detail'),
url(r'^tip/(?P<slug>[-\w]+)/$', views.ToolkitDetail.as_view(), name='toolkit_detail'),
)
#my models.py
from django.db import models
from django.core.urlresolvers import reverse
class Category(models.Model):
slug = models.SlugField()
title = models.CharField(max_length=250)
heading = models.CharField(max_length=750)
description = models.TextField()
link = models.URLField()
def get_absolute_url(self):
return reverse('category_detail', kwargs={'slug': self.slug})
#my views.py
class MyCategory(ListView):
model = Category
context_object_name = 'category'
template_name = 'category.html'
class CategoryDetail(DetailView):
slug_field = 'slug'
model = Category
slug_url_kwarg = 'slug'
context_object_name = 'category'
template_name = 'category_detail.html'
The above is the summation of my problem. Please any assistance is appreciated. I'm sure its clear enough my problem, but since StackOverflow won't let me post without adding more text, I'm doing so. I think the excerpt above is self explanatory as to my problem. I think I'm released to post now.
Your url name 'category_detail' has compulsory parameter - slug. So in template you could write:
View
As your model have special method for generating url you can do it simple:
{{ category.get_absolute_url }}
Your template contains {% url 'category_detail' %}, i.e. tries to reverse "category_detail" url pattern, without giving the required slug keyword argument. This might work:
{% url 'category_detail' slug="foo" %}

Django: routing same model but different category field to separate URLs

I have the following model and url routes. There is one Post model that I want to route to different URLs based on the category. Is there a way to do this by passing in extra information in app/urls.py?
In app/posts/models.py
class Post(models.Model):
author = ...
title = ...
body = ...
category = models.CharField()
In app/urls.py
urlpatterns = patterns(
'',
(r'^blog/', include('posts.urls'), {'category': 'blog'}),
(r'^school/', include('posts.urls'), {'category': 'school'}),
)
My understanding is that the extra info from app/urls.py is included in each url route in app/posts/urls.py. Is there a way to use that information? What can I put in place of the exclamation points below?
In app/posts/urls.py
from models import Post
queryset = Post.objects.order_by('-pub_date')
urlpatterns = patterns(
'django.views.generic.list_detail',
url(r'^$', 'object_list',
{'queryset': queryset.filter(category=!!!!!!)}
name="postRoot"),
url(r'^(?P<slug>[-\w]+)/$', 'object_detail',
{'queryset': queryset.filter(category=!!!!!!)},
name="postDetail")
)
Thanks, joe
I am not aware of a way to use the URL parameters the way you have indicated. If anyone knows better, do correct me.
I faced a similar situation some time ago and made do with a thin wrapper over the list_detail view.
# views.py
from django.views.generic.list_detail import object_list
def object_list_wrapper(*args, **kwargs):
category = kwargs.pop('category')
queryset = Post.objects.filter(category = category)
kwargs['queryset'] = queryset
return object_list(*args, **kwargs)
#urls.py
urlpatterns = patterns('myapp.views',
url(r'^$', 'object_list_wrapper', {}, name="postRoot"),
...