Django doesn't render the requested view - python

people. I'm a beginner Django developer so sorry if it's a basic question.
I have a webpage that shows a list of movies and each movie has a details view, but for some reason, the details view is never rendered.
#views.py
def index(request):
latest_movies = Movie.objects.order_by('-movie_id')[:5]
template = loader.get_template('ytsmirror/index.html')
context = {
'latest_movies' : latest_movies,
}
return HttpResponse(template.render(context, request))
def detail(request, movie_id):
movie = Movie.objects.get(movie_id=movie_id)
template = loader.get_template('ytsmirror/details.html')
context = {
'movie' : movie,
'plot': 'Lorem impsum',
}
return HttpResponse(template.render(context, request))
And my urls.py
#urls.py
from django.conf.urls import url
from . import views
app_name = 'ytsmirror'
urlpatterns = [
url(r'$', views.index, name='index'),
url(r'^(?P<movie_id>\d{4})$', views.detail, name='detail'),
]
When I try to reach /ytsmirror/4200/ for example, I don't get any error and Django apparently reaches the correct URL pattern but doesn't render the details view, it stays on the index view, without any change.
What am I doing wrong? Thanks.

url(r'$', views.index, name='index') matches the end of the string, so basically it will match any url, that's why your code isn't working. You need to replace url(r'$', views.index, name='index') with url(r'^$', views.index, name='index') so that it will match only empty url
^ asserts position at start of the string
$ asserts position at the end of the string, or before the line terminator right at the end of the string (if any)

Related

Django base.models.Post.DoesNotExist

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.

django 1.10 Application level URL does not recognize positional parameter

I'm trying to employ positional parameters on a view inside one app of my django application.
The app is called member. and the member/urls.py is called by the project trekfed:
trekfed.py
from member import urls as mviews
from public import views as pviews
urlpatterns = [
url(r'^member/', include(mviews)),
url(r'^admin/', admin.site.urls),
member\urls.py
urlpatterns = [
url(r'$', views.index, name='myprofile'),
url(r'^(?P<mbr>)/$', views.index, name='profile'),
url(r'^api/', include(router.urls)),
]
views.py
#login_required
def index(request, mbr=""):
print(mbr)
data = {}
if mbr:
user = User.objects.filter(Q(id=mbr)|Q(username=mbr)).values('User_id')
else:
user = request.user
data['user'] = user
data['member'] = models.Member.objects.get(User=user)
data['Address'] = models.Address.objects.filter(User=user).get(Primary=True)
data['Phone'] = models.Phone.objects.filter(User=user).get(Primary=True)
data['Family'] = models.Family.objects.filter(Primary=user.member)
data['Sponsor'] = models.Family.objects.filter(Dependent=user.member.pk)
data['rank'] = models.Promotion.objects.filter(User=user).latest('Date_Effective')
return render(request, "member/profile/page_user_profile.html", data)
when authenticated, if I go to http://localhost:8000/member/ I can see my profile. No problems.
If I go to http://localhost:8000/member/user2/ I still see my profile, not user2's.
Is there something that I'm missing here? Thanks.
Update 1
Tried:
url(r'^(?P<mbr>[a-zA-Z0-9]+)/$', views.index, name='profile'),
and
url(r'^(?P<mbr>.+)/$', views.index, name='profile'),
with no change.
Yes there is something you're missing here and it's called regex pattern.
In your urls the url(r'^(?P<mbr>)/$'), pattern does not matches anything (it's just an empty string, ''). You should first think of what pattern you want to capture (say only words, only digits, both words and digits, both word and digits and -, both words and digits and - and _ etc.
It all depends on the captured pattern. Take a look at here for some common url patterns and whatever you choose, place it after the > character (url(r'^(?P<mbr>regex_pattern_here)/$'),).
If you want to make it an optional field then you still have to enter a regex pattern (in case something matches) and leave your urls as is:
urlpatterns = [
url(r'^$', views.index, name='myprofile'),
url(r'^(?P<mbr>regex_pattern_here)/$', views.index, name='profile'),
url(r'^api/', include(router.urls)),
]
With this approach, both http://localhost:8000/member/ (without an mbr) and http://localhost:8000/member/user2/ (with mbr = user2) will hit the views.index view.
[BONUS]: You can test your regex patterns in http://pythex.org/

Reverse for 'get_post' with arguments '()' and keyword arguments '{'slug': 'sample-post'}' not found

I am using django 1.9. While implementing class based views and urlpatterns I am not able to redirect my particular link to corresponding post.
settings/urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from posts.views import Home
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^post/', include("posts.urls")),
url(r'^$', Home.as_view(), name="blog_home"),
]
posts/urls.py
from django.conf.urls import url, include
from .views import Display
urlpatterns = [
url(r'^(?P<slug>\w+)/$', Display.as_view(), name="get_post"),
]
posts/views.py
class Display(View):
def get(self, request, slug):
params = {}
params['post'] = Post.objects.get(slug=slug)
return render(request, "blog/viewpost.html", params)
def post(self, request):
pass
and my error follows:
error is shown in that image
When you use the url regex r'^(?P<slug>\w+)/$, the \w matches alphanumeric characters and underscore. It will not, however, match hyphens -.
So, when your template looks for a URL with slug equal to sample-post, the above regex will not find a match. You should try using this instead:
urlpatterns = [
url(r'^(?P<slug>[-\w]+)/$', Display.as_view(), name="get_post"),
]

Django reverse lookup rendering the same (wrong) template

I have a small resume site that is not rendering a different template upon hitting a reversed URL.
site/scripts/templates/scripts/index.html:
<p>were at main</p>
python
<br/>
bash
These links 'python' and 'bash' work in the URL bar, they take us to localhost:scripts/bash/ and localhost:scripts/python/, but the exact same webpage is displayed (index.html, or localhost:scripts/)
site/scripts/urls.py:
from django.conf.urls import patterns, include, url
from scripts import views
urlpatterns = patterns('',
url(r'$', views.index, name='index'),
url(r'python/$', views.access_python, name='python'),
url(r'bash/$', views.access_bash, name='bash'),
)
site/scripts/views.py:
from django.shortcuts import render
def index(request):
return render(request, 'scripts/index.html')
def access_python(request):
return render(request, 'scripts/python.html')
def access_bash(request):
return render(request, 'scripts/bash.html')
site/urls.py (main folder w/ settings.py):
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'scripts/', include('scripts.urls', namespace='scripts')),
)
clicking 'bash' should retrieve:
site/scripts/templates/scripts/bash.html:
<p>we're at bash</p>
Why would a reverse lookup reach the correct URL, but not call the associated view that that URL pattern wants? Thank you
The index regex was catching any possible pattern, since it matched any end of string. I found out by moving the index pattern after the other 2. It should be:
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^python/$', views.access_python, name='python'),
url(r'^bash/$', views.access_bash, name='bash'),
)
Any blank index urls (r'^$') need both start and end of string, to match the empty string after the first part of that pattern (in this case, 'scripts/')

404 error Django

I'm beginner in Django programing, and I want to show a view on my browser.
My code is:
polls/view.py:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
def animal(request):
return HttpResponse("Hello cat")
polls/urls.py:
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^animal$', views.animal, name='animal'),
)
When I show index view, everything in okay. But, when I show animal view, my browser not found the page, and I dont know why.
Thank you !
Your second URL pattern isn't terminated. It needs to be:
url(r'^animal/$', views.animal, name='animal')
also, you want to list your URLs from most specific to least specific. Also note that you can use the patterns prefix to keep your code a bit more DRY.
urlpatterns = patterns('views',
url(r'^animal/$', 'animal', name='animal'),
url(r'^$', 'index', name='index'),
)
as Django will try to match them top-down

Categories