I am very new to django. I have followed the steps from a video on youtube on how to create a simple blog. Basically, I have a portfolio main page that displays several things including the latest blogs. It all works well. I can see the latest posts on the main page. I can also click in each of them and they open up fine.
However, now, I want to create a new page (blog.html) that will hold all the posts. I created a blog.html and did the necessary settings in views.py and urls.py. However, for some reason I get an error when trying to access localhost/blog/
This is my urls.py:
urlpatterns = [
path('', views.home, name='home'),
path('work/', views.work, name='work'),
path('<slug:slug>/', views.post_detail, name='post_detail'),
path('blog/', views.blog, name='blog'),
]
Here views.py:
def home(request):
posts = Post.objects.all()
return render(request, 'home.html', {'posts': posts})
def post_detail(request, slug):
post = Post.objects.get(slug=slug)
return render(request, 'post_detail.html', {'post': post})
def blog(request):
posts = Post.objects.all()
return render(request, 'blog.html', {'posts': posts})
This happens if you trigger the post_detail view with a slug, and no Post with that slug exists. But here you simply trigger the wrong view. This is because <slug:slug>/ will also match blog/, so you will never trigger the blog/ view. You should reorder the views, so:
urlpatterns = [
path('', views.home, name='home'),
path('work/', views.work, name='work'),
# before <slug:slug>
path('blog/', views.blog, name='blog'),
path('<slug:slug>/', views.post_detail, name='post_detail'),
]
It might however be better to make non-overlapping patterns, since now if you ever make a Post with blog as slug, that post is inacessible. You thus might want to rewrite the path to:
urlpatterns = [
path('', views.home, name='home'),
path('work/', views.work, name='work'),
path('blog/', views.blog, name='blog'),
# non-overlapping patterns
path('post/<slug:slug>/', views.post_detail, name='post_detail'),
]
Note: It is often better to use get_object_or_404(…) [Django-doc],
then to use .get(…) [Django-doc] directly. In case the object does not exists,
for example because the user altered the URL themselves, the get_object_or_404(…) will result in returning a HTTP 404 Not Found response, whereas using
.get(…) will result in a HTTP 500 Server Error.
Related
I got the error Page not found (404) when I try to reach the 'contact.html' and 'about.html' page
I don't understand why I'm getting this.
Here is my code:
app/urls.py:
urlpatterns = [
path('', views.frontpage, name="frontpage"),
path('<slug:slug>/', views.article, name="article"),
path('contact/', views.contact, name="contact"),
path('about/', views.about, name="about"), # If I write '/about/' that's working but the url is 'http://127.0.0.1:8000/%2Fabout/' and not 'http://127.0.0.1:8000/contact/' as i want. Same issue for contact
]
app/views.py:
def contact(request):
return render(request, 'contact.html')
def about(request):
return render(request, 'about.html')
# Of course the html file are created, they are located in the template folder
I'm trying to reach each page with this html code:
Home # This is working
Contact # This is not working
Aboout # This is not working
(citrouille is my app's name)
Here is the mysite/urls.py (root folder):
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('citrouille.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I have others functions working perfectly such as the article page with the slug. But this two pages doesn't want to show. I'm pretty sure this is a stupid error but i can't point it.
Thank you for the help
Site doesn't show admin panel. What should I do?
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8001/admin/
Raised by: news.views.PageViews
With what it could be connected? I don't know what to do.
class PageViews(ListView):
template_name = 'page.html'
paginate_by = 8
context_object_name = 'posts'
ordering = ['-datetime']
model = Page
paginate_orphans = 1
def dispatch(self, request, *args, **kwargs):
slug = kwargs.get('slug')
try:
self.category = Category.objects.get(slug=slug)
except Category.DoesNotExist:
raise Http404
return super().dispatch(request, *args, **kwargs)
def get_queryset(self):
return Page.objects.filter(category=self.category)
My urls below:
path("register/", views.register, name="register"),
path("logout/", views.logout_request, name="logout"),
path("login/", views.login_request, name="login"),
path("profile/", views.account, name="account"),
path('', HomeView.as_view(), name='home'),
path('<slug:slug>/', views.PageViews.as_view(), name='page'),
path('robots.txt', views.robots_view),
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('summernote/', include('django_summernote.urls')),
I'd bet that your url controller for PageViews is too broad and Django tries to execute PageViews with slag 'admin' instead of opening the admin site.
Please, note that it's just a wild guess - you question is very hard to answer. Read this before posting another one: How do I ask a good question
Django checks URL patterns in order. Since "admin" would be valid as a slug, the URL matches against the PageViews pattern and that view is called.
The solution is to put the more specific URLs, in this case admin, at the top of the list.
You just need to change the order of your URLs. Django tries them from top to bottom. What is happening is that Django is processing 'admin' as a slug and trying to find a url with a slug with admin.
Change your urls.py to something like this:
path("register/", views.register, name="register"),
path("logout/", views.logout_request, name="logout"),
path("login/", views.login_request, name="login"),
path("profile/", views.account, name="account"),
path('admin/', admin.site.urls), #move your admin/ to here
path('', HomeView.as_view(), name='home'),
path('<slug:slug>/', views.PageViews.as_view(), name='page'), #where your admin url is going to get 404ed
path('robots.txt', views.robots_view),
path('accounts/', include('django.contrib.auth.urls')),
path('summernote/', include('django_summernote.urls')),
I have this structure of urls:
page/section/subsection/article, where section, subsection and article are user-generated slug names.
How can I write the urlpatterns?
I do this, but may be exist better method?
urlpatterns = [
url(r'^$', views.index),
url(r'^(?P<slug>[-\w]+)/$', views.section),
url(r'^(?P<slug>[-\w]+)/(?P<subslug>[-\w]+)/$', views.subsection),
url(r'^(?P<slug>[-\w]+)/(?P<subslug>[-\w]+)/(?P<articleslug>[-\w]+)/$', views.article)
]
My views:
def index(request):
return render(request, 'MotherBeeApp/index.html', {})
def section(request, slug):
sections = Section.objects.filter(page=slug)
if sections:
return render(request, 'MotherBeeApp/section.html', {'Sections': sections})
else:
return render(request, 'MotherBeeApp/404.html', status=404)
def subsection(request, slug, subslug):
subsection = Section.objects.get(link_title=subslug)
articles = Article.objects.filter(section=subsection.pk)
page_title = subsection.title
return render(request, 'MotherBeeApp/subsection.html', {'Articles': articles, 'PageTitle': page_title})
def article(request, slug, subslug, articleslug):
article = Article.objects.get(link_title=articleslug)
return render(request, 'MotherBeeApp/article.html', {'Article': article})
If you are using Django version older than Django 2.0 (< 2.0) than you are doing right thing and you are already using optimistic way. but if your Django version is later than or equals to Django 2.0 you could write urlpatterns as shown here.
Maybe you can upgrade your Django to 2.0+, and then use code as follows:
from django.urls import path, include
urlpatterns = [
path('', views.index),
path('<slug:slug>/', include([
path('', views.section),
path('<slug:subslug>/', views.subsection),
path('<slug:subslug>/<articleslug>/', views.article),
])),
]
I am new to Django and I am just trying to pass arguments to Django generic base View and it is not showing up in terminal as I am printing the arguments passed.
views.py
from django.views.generic import View
class CartView(View):
def get(self, request, *args, **kwargs):
item = request.GET.get('item')
qty = request.GET.get('qty')
print item, qty
return HttpResponseRedirect('/')
urls.py:
urlpatterns = [
url(r'^home/$', 'newsletter.views.home', name='home'),
url(r'^contact/$', 'newsletter.views.contact', name='contact'),
url(r'^about/$', 'dressika.views.about', name='about'),
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^', include('products.urls')),
url(r'^categories/', include('products.urls_categories')),
url(r'^cart/', CartView.as_view(), name='cart'),
When I add some data in browser like "localhost:8000/cart/?item=2&qty=5" it is not showing the arguments in terminal according to above code. By only typing "localhost:8000/cart/" it does redirects me to homepage. But with arguments it shows 404.
It sounds like you may have to fix the entry in urls.py routing to the view. Could you post your urls.py as well?
I have created custom index view. urls.py:
url(r'^', include('cms.urls')),
url(r'^', 'myapp.views.index', name='index'),
in views.py:
from cms.utils import get_template_from_request
def index(request):
template = get_template_from_request(request)
.....
return render(request, template)
When i try to access django admin 127.0.0.1:8000/admin i get an error
'NoneType' object has no attribute 'pk'
because in my index.html is templatetag {% product_list request.current_page %} which requires current_page to be in request. I think this happens because django renders my index page in django admin, where it shouldn't. What can i do to fix this?
I think the easiest way to fix your problem is to include the urls of the admin site before those 'index' and 'cms' as explained in the Django documentation site. Your url patterns in the urls.py file would be something like this:
...
url(r'^admin/', admin.site.urls),
url(r'^', include('cms.urls')),
url(r'^', 'myapp.views.index', name='index'),
...
Previously i had url(r'^myapp/', include('myapp.urls')), changed to url(r'^', include('myapp.urls')) and it's working.