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'),
Related
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).
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...
I followed the qblog tutorial, using python 2.7.10 and django 1.9.5.
When i enter the admin's blog interface, and clicked add blog entry, then it shown me below:
TemplateDoesNotExist at /admin/blog/entry/add/
django_markdown/editor_init.html
but i have installed django-markdown already. I would like to show the code below:
models.py:
class Entry(models.Model):
title = models.CharField(max_length=200)
body = MarkdownField()
slug = models.SlugField(max_length=200, unique=True)
publish = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
tags = models.ManyToManyField(Tag)
objects = EntryQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("entry_detail", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog Entry"
verbose_name_plural = "Blog Entries"
ordering = ["-created"]
admin.py:
from django.contrib import admin
from . import models
from django_markdown.admin import MarkdownModelAdmin
from django_markdown.widgets import AdminMarkdownWidget
from django.db.models import TextField
class EntryAdmin(MarkdownModelAdmin):
list_display = ("title", "created")
prepopulated_fields = {"slug": ("title",)}
# Next line is a workaround for Python 2.x
formfield_overrides = {TextField: {'widget': AdminMarkdownWidget}}
admin.site.register(models.Entry, EntryAdmin)
admin.site.register(models.Tag)
qblog/urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
import settings
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)),
url(r'^markdown/', include("django_markdown.urls")),
url(r'^', include('blog.urls')),
)
if settings.DEBUG:
from django.conf.urls.static import static
urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
You need to add the editor_init.html file in your project.
If your project root is project/ there should be a directory called templates in there. If that directory does not exist, create it (so the path would be project/templates).
Place the editor_init.html file in this directory and everything should work.
You can find more information about setting up templates here and in the django docs.
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.
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>