Django template failling despite my effort to learn it - python

categories.html # this is what i want to be called by CategoryView.as_view() which never works. Howevwer index.html works but i have hardcoded the link as follows within index.html. Although index.html extends base.html which is where am outputing the url.
Edit: Avoid confusion this is what is available in index.html template which i guess should work but shows the following error for index now Page not found (404)
<li>All</li>
from my root directory when i type http://127.0.0.1:8000 it works but i want something like this http://127.0.0.1:8000/cartegories/(index.html or categories.html) i assume the index.html or categories.html is not visible when typed, which is fine.
I can’t believe this is taking me 12hours with all possible intuitive tweaking still can’t get it to work. Please someone advise what am doing wrong. In essense i am just outputing hellow world in categories.html but later i would iterate through and list all the categories in my blog… if hello world can’t work then nothing will..
#posts urls.py
from django.conf.urls import include, url
from django.contrib import admin
from .views import IndexView, CategoryView
urlpatterns = [
url(r'^$', IndexView.as_view(), name='index'),
url(r'^all_categories$', CategoryView.as_view(), name='all_categories'),
# stuff i have tried
]
#admin urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^/', include('posts.urls', namespace="posts")),
url(r'^admin/', include(admin.site.urls)),
]
#views.py
from django.shortcuts import render
from .models import Post, Comment, Category, Reply
from django.views import generic
class IndexView(generic.ListView):
template_name = 'posts/index.html'
context_object_name = 'posts'
model = Post
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['categories'] = Category.objects.all()
return context
class CategoryView(generic.ListView):
template_name = 'posts/categories.html'
context_object_name = 'categories'
model = Category
#modesl.py
class Category(models.Model):
category_name = models.CharField(max_length=200)
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.category_name
def get_absolute_url(self):
return reverse('all_categories')
class Post(models.Model):
title = models.CharField(max_length=200)
…
category = models.ForeignKey(Category)
def save(self, *args, **kargs):
if not self.id:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kargs)
def __str__(self):
return self.title

Changing the order of the URLs in the files solved the problem. Generally, the order of the main urls.py is important for readability but the / slash did the trick
#admin urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^/', include('posts.urls', namespace="posts")),
url(r'^admin/', include(admin.site.urls)),
]
Also in the post/url.py file i added a / at the end of the regex
urlpatterns = [
url(r'^$', IndexView.as_view(), name='index'),
url(r'^categories/$', CategoryView.as_view(), name='all_categories'),
]
Finally in the template the html read as follows:
<li>All</li>

Related

Django No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model

Hi I am trying to create a blog using the Django webframework.
I get the error,
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
The urls.py is given below,
from django.urls import path
from .views import (
BlogListView,
BlogDetailView,
BlogCreateView,
BlogUpdateView,
)
urlpatterns = [
path('post/<int:pk>/edit', BlogUpdateView.as_view(), name='post_edit'),
path('post/new/', BlogCreateView.as_view(), name='post_new'),
path('post/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),
path('', BlogListView.as_view(), name='home'),
]
The models.py is given below,
from django.db import models
from django.urls import reverse
# Create your models here.
MAX_LENGTH = 500
class Post(models.Model):
title = models.CharField(max_length=MAX_LENGTH)
author = models.ForeignKey('auth.User', on_delete=models.CASCADE,)
body = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
Where am I going wrong?
From your indentation it looks as if your methods on the Post class are instead in the global scope. They should have the same indendation as the title, author and body field (i.e. 4 spaces/1 tab).

Is there any way to make a second LOGIN_REDIRECT_URL in settings.py in Django?

I am creating an app in Django which have two external users:
1. Teacher
2. Student
I have to create total of 3 apps, one the base app that contains home.html template, other the student app that contains student.html template and third teacher app that contains teacher.html template.
I have just created two apps for now, base app and student app, I have created login, logout and register pages for student app, now I am successfully able to redirect the user (student) to the student.html whenever the student logs into the system and I did this by putting LOGIN_REDIRECT_URL = 'student' in my settings.py.
I want to do the same for Teacher app as well but I want to redirect teacher to the teacher.html.
Is there any way that I can create the second LOGIN_REDIRECT_URL in settings.py to fulfil this purpose or it will be done any other way?
My Project Structure
django_project
|__esacp(main system)
|_____migrations
|_____templates
|________esacp
|__________base.html
|__________home.html
|__________student.html
|__________teacher.html
|_____apps.py
|_____forms.py
|_____models.py
|_____views.py
|__django_project
|__student
|_____migrations
|_____templates
|________student
|___________login.html
|___________logout.html
|___________register.html
|_____apps.py
|_____forms.py
|_____models.py
|_____views.py
|__teacher
|__db.sqlite3
|__manage.py
Code of models.py of esacp app
from django.db import models
from django.utils import timezone
class StudentType(models.Model):
studenttype_id = models.IntegerField(primary_key=True)
type_title = models.CharField(max_length=50)
def __str__(self):
return self.type_title
class StudentDetails(models.Model):
name = models.CharField(max_length=50)
username = models.CharField(max_length=50, primary_key=True)
password = models.CharField(max_length=50)
email_id = models.CharField(max_length=100)
contact = models.CharField(max_length=100)
studenttype = models.ForeignKey(StudentType, on_delete=models.CASCADE)
registration_date = models.DateTimeField(default=timezone.now)
modify_date = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
Code of urls.py of esacp app
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='esacp-home'),
path('student', views.student, name='student'),
]
Code of urls.py of main project
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import path, include
from users import views as user_views
urlpatterns = [
path('admin/', admin.site.urls),
path('register/', user_views.register, name='register'),
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
path('tlogin/', auth_views.LoginView.as_view(template_name='teacher/tlogin.html'), name='tlogin'),
path('tlogout/', auth_views.LogoutView.as_view(template_name='teacher/tlogout.html'), name='tlogout'),
path('esacp/', include('esacp.urls')),
Code of views.py of teacher app
from django.shortcuts import render
from django.contrib.auth.views import LoginView
class MyLoginView():
def get_success_url(self):
url = self.get_redirect_url()
return url
Code of views.py of esacp app
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
def home(request):
return render(request, 'esacp/home.html')
#login_required
def student(request):
return render(request, 'esacp/student.html')
and below I have the statement in setting.py
LOGIN_REDIRECT_URL = 'student'
You have two login URLs. Therefore you can use a different login view for each one, and override get_success_url so that you are redirected to the correct page after login.
For example, the teacher login view would look something like:
from django.contrib.auth.views import LoginView
class TeacherLoginView(LoginView):
template_name = 'teacher/tlogin.html'
def get_success_url(self):
url = self.get_redirect_url()
return url or '/teacher/' # FIXME use reverse here instead of hardcoding the URL
Then use that view instead of TeacherView in your URL patterns.
path('login/', TeacherLoginView.as_view(), name='login'),

Image not showing in Django [duplicate]

This question already has answers here:
How to display images from model in Django?
(3 answers)
Closed 5 years ago.
I don't know why the images aren't showing in Django. Something to do with the media root?
settings code
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')'
models code
from django.db import models
from django.core.urlresolvers import reverse
Create your models here.
class Post(models.Model):
## Post Properties
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True)
summary = models.CharField(max_length=255)
content = models.TextField()
published = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to='img',default='media/placeholder.png')
class Meta:
ordering = ['-created']
def __unicode__(self):
return u'%s'% self.title
def get_absolute_url(self):
return reverse('blog.views.post', args=[self.slug])
I didn't add a url for the picture, could that be a problem?
urls
urlpatterns = [
url(r'^post/(.*)', blogViews.post),
url(r'^about/$', blogViews.about),
url(r'^$', blogViews.index),
url(r'^admin/', admin.site.urls),
index.html code
<img src="{{post.image}}">
<p> {{post.image}} </p>
**Views.py **
from django.shortcuts import render, render_to_response, get_object_or_404
from django.http import HttpResponse
from .models import Post
# Create your views here.
def index(request):
posts = Post.objects.all()
return render(request, 'index.html', {'posts': posts})
def post(request, slug):
return render_to_response('post.html', {
'post': get_object_or_404(Post,slug=slug)
})
def about(request):
return render(request, 'about.html', {})
In the website all that shows is a blank picture as well as the file name (either 'placeholder.png' which is the default or img/... which I uploaded through admin)
Edit:
This was marked as a duplicate, I saw that post and tried to change my code to reflect that code but it wasn't working. Figured it would be better to post my own.
Thanks in advance, first question on this site!
Try this,
<img src="{{post.image.url}}">
Also, add in your urls.py,
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
For learning more about serving static, refer the documentation here...

Django slug throws me an error and url is not matching

I've followed the advice I was given but the slug still does not show in the url. When I try to run it I get the following error:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8080/blog/1/
Raised by: blog.views.detail
I was told if I changed the values in my views from
detail(request, blog_id):
page = "blog/detail.html"
title = "Detail"
context = {
"post": get_object_or_404(Post, pk=blog_id),
}
to this
detail(request, slug):
page = "blog/detail.html"
title = "Detail"
context = {
"post": get_object_or_404(Post, slug=slug),
}
and changed my url to look like this
url(r'^(?P<slug>[\w-]+)/$', views.detail, name='detail'),
it would work but it does not. Heres my code as it is now below.
My post model in models.py looks like this
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
slug = models.SlugField()
img = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
author = models.ForeignKey(Author)
categories = models.ManyToManyField(Category)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.title
class Meta:
ordering = ["-created"]
my views.py looks like this
from django.shortcuts import render, get_object_or_404
from .models import Post
def detail(request, slug):
page = "blog/detail.html"
title = "Detail"
context = {
"post": get_object_or_404(Post, slug=slug),
"title": title,
}
return render(request, page, context)
my blog/urls.py look like this
from django.conf.urls import url
app_name = 'blog'
from . import views
urlpatterns = [
# ex: /blog/
url(r'^$', views.index, name='index'),
# ex: /blog/5/
url(r'^(?P<slug>[\w-]+)/$', views.detail, name='detail'),
# ex: /blog/contact
url(r'^contact$', views.contact, name='contact'),
]
my site/urls.py looks like this
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^blog/', include('blog.urls')),
url(r'^admin/', admin.site.urls),
url(r'^$', 'blog.views.land'),
]
my admin.py looks like this
from django.contrib import admin
from .models import Post, Author, Category, Tag
class PostAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
search_fields = ['title', 'body']
list_display = ['title', 'body', 'created']
list_filter = ['created']
admin.site.register(Post, PostAdmin)
any and all help guidance advice or tutorial is invited and welcomed. Thanks
As I can see from your post: you tried url http://localhost:8080/blog/1/, but that is the old url, you need new URL which is going to be something like http://localhost:8080/blog/slug/...
You should also change get_object_or_404(Post, slug) to get_object_or_404(Post, slug=slug).
See https://docs.djangoproject.com/en/1.9/_modules/django/shortcuts/#get_object_or_404 for details, get expects keyword arguments, not positional: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#django.db.models.query.QuerySet.get
the regex is this
(?P<slug>[\w-]+)
when it should be this
(?P<slug>[\w\-]+)
thanks to all that tried to help. I'm glad I didn't give up. This made my new years!!!
Check if you really have a post with slug 1. It seems to me that you used /blog/1 to get the post by pk and so now it won't work as the post with slug 1 doesn't exist at all.

Django "Page not found (404)"

I think I done everything correct but I don't know why it doesn't work. When I try to reach a page I get error "Page not found (404)".
So, this all products page works 127.0.0.1:8000/products/ but when I try to visit single product page 127.0.0.1:8000/products/audi I get error that it's not found...
So, maybe you what's wrong here?
Thank you.
Page not found (404)
Request Method: GET
Request URL: http://link/products/audi
Using the URLconf defined in ecommerce.urls, Django tried these URL patterns, in this order:
^static/(?P<path>.*)$
^media/(?P<path>.*)$
^admin/doc/
^admin/
^products/ ^$ [name='products']
^products/ ^$(?P<slug>.*)/$
^contact/ [name='contact_us']
The current URL, products/audi, didn't match any of these.
Main project urls.py:
from django.conf import settings
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.STATIC_ROOT
}),
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT
}),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^products/', include('products.urls')),
url(r'^contact/', 'contact.views.contact_us', name='contact_us'),
)
Products app urls.py:
from django.conf import settings
from django.conf.urls import patterns, include, url
urlpatterns = patterns('products.views',
url(r'^$', 'all_products', name='products'),
url(r'^$(?P<slug>.*)/$', 'single_product'),
)
views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, RequestContext, get_object_or_404
from .models import Product
def all_products(request):
products = Product.objects.filter(active=True)
return render_to_response('products/all.html', locals(), context_instance=RequestContext(request))
def single_product(request, slug):
product = get_object_or_404(Product, slug=slug)
return render_to_response('products/single.html', locals(), context_instance=RequestContext(request))
models.py
from django.db import models
# Create your models here.
class Product(models.Model):
title = models.CharField(max_length=220)
description = models.CharField(max_length=3000, null=True, blank=True)
price = models.DecimalField(max_digits=1000, decimal_places=2, null=True, blank=True)
slug = models.SlugField()
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title',]
class ProductImage(models.Model):
product = models.ForeignKey(Product)
description = models.CharField(max_length=3000, null=True, blank=True)
image = models.ImageField(upload_to='product/images/')
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __unicode__(self):
return self.image
Your URL pattern has an extra $ at the beginning, so it can never match anything:
url(r'^$(?P<slug>.*)/$', 'single_product')
This should be:
url(r'^(?P<slug>.*)/$', 'single_product')
This still requires a trailing slash, which is the normal pattern. With that corrected, your URL should be /products/audi/. You don't show the context in which that URL is created, but this is one example of why it's a good idea to use Django's url reversal to build URLs if at all possible. That would look something like this, in Python code (for instance, possibly in a get_absolute_url method on the model:
reverse('single_product', kwargs={'slug': someproduct.slug})
Or like this, in a template:
Django 1.5:
{% url 'single_product' someproduct.slug %}
Django 1.4 and earlier:
{% url single_product someproduct.slug %}
You have a typo:
url(r'^$(?P<slug>.*)/$', 'single_product'),
Note this $ just after ^, in regexp it states for a string end. Replace with
url(r'^(?P<slug>.*)/$', 'single_product'),

Categories