Django; Will not make the correct request - python

I am just beginning to learn how to use django. I have set up my views.py, urls.py, settings.py, and relative HTML pages. I am able to get the index page to come up but not the about page (only outputs some text) or my category page. I am assuming that the problem is affecting them both.
Views.py:
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import render_to_response
from rango.models import Category
from rango.models import Page
def index(request):
# Obtain the context from the HTTP request.
context = RequestContext(request)
category_list = Category.objects.order_by('id')[:5]
context_dict = {'categories': category_list}
# Render the response and send it back!
return render_to_response('index.html', context_dict, context)
def about(request):
# Request the context of the request.
# The context contains information such as the client's machine details, for example.
context = RequestContext(request)
context_dict = {'boldmessage': "I am from the context"}
return render_to_response('/about.html', context_dict, context)
def category(request, category_name_url):
# Request our context from the request passed to us.
context = RequestContext(request)
category_name = category_name_url.replace('_', ' ')
context_dict = {'category_name': category_name}
try:
category = Category.objects.get(name=category_name)
pages = Page.objects.filter(category=category)
# Adds our results list to the template context under name pages.
context_dict['pages'] = pages
context_dict['category'] = category
except Category.DoesNotExist:
# Go render the response and return it to the client.
return render_to_response('rango/category.html', context_dict, context)
urls.py:
from django.conf.urls import patterns, url
from rango import views
# At the top of your urls.py file, add the following line:
from django.conf import settings
urlpatterns = patterns('',
url(r'$', views.index,name='index'),
url(r'about/$', views.about,name='about'))
#url(r'category/$', views.category,name='category'))
# UNDERNEATH your urlpatterns definition, add the following two lines:
if settings.DEBUG:
urlpatterns += patterns(
'django.views.static',
(r'media/(?P<path>.*)','serve',{'document_root': settings.MEDIA_ROOT}), )
My template directory has been hard coded so it really shouldn't be a problem
TEMPLATE_DIRS = ('C:/Users/aharon/Desktop/TEMP',)
Keep in mind that I am very noob so please be easy on me and I would like as much explanation as possible. Thank You!

You have not anchored your regexes with ^ at the start. Without that, your first pattern will match every single URL. You should makes sure they all start with ^.

Related

In my Django project I have two similar url

I have a question with my sites urls. When someone want to go mysite.com I redirect them to mysite.com/register.
url(r'^$', RedirectView.as_view(url='register/', permanent=False), name='index'),
url(r'^register/',views.guaform2,name='custform2'),
Also I have another url that allows to write somethings after the part of register. For example when someone goes to this website mysite.com/register/kh-54-m2-fc it allows to go that:
url(r'^register/(?P<pk>[-\w]+)',views.guaform,name='custform'),
But when I use these urls together my guaform view doesn't work. And it goes to customer_form2.html. When someone goes this site: mysite.com/register/ anything I want them go to customer_form.html. How can I seperate these urls?
urls.py
from django.conf.urls import url
from django.contrib import admin
from olvapp import views
from django.views.generic import RedirectView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', RedirectView.as_view(url='register/', permanent=False), name='index'),
url(r'^register/',views.guaform2,name='custform2'),
url(r'^register/(?P<pk>[-\w]+)',views.guaform,name='custform'),
]
views.py
from django.shortcuts import render,HttpResponse
from olvapp.models import Customer
from olvapp.forms import CustomerForm,CustomerForm2
from django.conf import settings
from django.http import HttpResponseRedirect
from django.urls import reverse
from olvapp import forms
def guaform(request,pk):
theurl = request.get_full_path()
orderid = theurl[10:]
form = CustomerForm(initial={'order_id':orderid})
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect(reverse('thank'))
else:
HttpResponse("Error from invalid")
return render(request,'customer_form.html',{'form':form})
def guaform2(request):
form = CustomerForm2()
if request.method == "POST":
form = CustomerForm2(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect(reverse('thank'))
else:
HttpResponse("Error from invalid")
return render(request,'customer_form2.html',{'form':form})
It should be enough to lock down the regular expression so it doesn't match in both cases.
Tighten the custform2 regex by using an dollar sign on the end to mark the end of the input:
url(r'^register/$',views.guaform2,name='custform2'),
That should be enough to get things working

How do I test endpoints registered with Wagtail Hooks?

Background
OK, I have a library wagtail_references which, like many snippet libraries, uses wagtail hooks to add admin views into the wagtail CMS.
Say I have, in my wagtail_hooks.py
#hooks.register('register_admin_urls')
def register_admin_urls():
return [
url(r'^references/', include(admin_urls, namespace='wagtailreferences')),
]
And the views that get registered are in views/reference.py:
#permission_checker.require('add')
def add(request):
Reference = get_reference_model()
ReferenceForm = get_reference_form(Reference)
if request.method == 'POST':
# STUFF I WANT TO TEST BECAUSE IT DOESN'T WORK PROPERLY
else:
form = ReferenceForm(user=request.user)
return render(request, "wagtail_references/references/add.html", {'form': form})
So in my test_stuff.py file, I'd have:
class TestReferenceIndexView(TestCase, WagtailTestUtils):
def setUp(self):
self.login()
def post(self, params=None):
params = params if params else {}
return self.client.post(reverse('wagtailreferences:add'), params)
def test_simple(self):
response = self.post()
self.assertEqual(response.status_code, 201)
The Problem
But test_simple fails, because of course the urls for the view its testing are hooked in dynamically, not defined in urls.py. I get:
django.urls.exceptions.NoReverseMatch: 'wagtailreferences' is not a registered namespace
The question
How can I test endpoints whose URLs are registered by wagtail hooks?
I've tried
Registering the hooks manually in the test case, like:
class TestReferenceIndexView(TestCase, WagtailTestUtils):
def setUp(self):
self.register_hook('register_admin_urls', register_admin_urls)
DOH! I hadn't registered the admin urls in my test app.
tests/urls.py looked like this:
from django.conf.urls import include, url
from wagtail.core import urls as wagtail_urls
urlpatterns = [
url(r'', include(wagtail_urls)),
]
But now looks like this:
from django.conf.urls import include, url
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
urlpatterns = [
url(r'^admin/', include(wagtailadmin_urls)),
url(r'', include(wagtail_urls)),
]
Fixed. Sigh.

Django-reverse URL's

I'm experimenting with Django forms. I'm trying to create a form which will accept the name of a city as input and output coordinates as output. My apps name is rango. I'm having a lot of trouble in URL reverse after accepting the input of the form..
My project/urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
import os
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^rango/',include('rango.urls', namespace="rango")),
)
if settings.DEBUG:
urlpatterns += patterns(
'django.views.static',
(r'media/(?P<path>.*)',
'serve',
{'document_root': settings.MEDIA_ROOT}), )
My rango/urls.py (rango is the name of the app):
from django.conf.urls import patterns, url
from rango import views
urlpatterns = patterns('',
url(r'^welcome/$', views.index, name='index'),
url(r'^about/$', views.about, name='about_page'),
url(r'^categories/(?P<name_dir>\w+)/$',views.cats,name='cats'),
url(r'^disp_page/(?P<city>\w+)/$',views.geo,name='coods'),
url(r'^disp_page/$', views.disp_page, name='disp_page')
My forms.py:
from django import forms
from rango.models import Page, Category
class PageForm(forms.ModelForm):
title = forms.CharField(max_length=128, help_text="Please enter the name of the city.")
#url = forms.URLField(max_length=200, help_text="Please enter the URL of the page.")
#views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
class Meta:
# Provide an association between the ModelForm and a model
model = Page
exclude = ('category','url','views')
My views.py:
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import render_to_response
from rango.models import Category,Page
from pygeocoder import Geocoder
from rango.forms import PageForm
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
import operator
# Create your views here.
def geo(request,city):
context = RequestContext(request)
citydata=Geocoder.geocode(city)
codtuple=citydata[0].coordinates
codtuple=list(codtuple)
context_dict = {'cood':codtuple}
return render_to_response('coods.html',context_dict,context)
def disp_page(request):
# A HTTP POST?
if request.method == 'POST':
form = PageForm(request.POST)
# Have we been provided with a valid form?
if form.is_valid():
# Save the new category to the database.
#form.save(commit=True)
city = form.cleaned_data['title']
# context = RequestContext(request)
#citydata=Geocoder.geocode(cityname)
#codtuple=citydata[0].coordinates
#codtuple=list(codtuple)
#context_dict = {'cood':codtuple}
return HttpResponseRedirect(reverse('rango:geo', args=(request,city)))
else:
# The supplied form contained errors - just print them to the terminal.
print form.errors
else:
# If the request was not a POST, display the form to enter details.
form = PageForm()
# Bad form (or form details), no form supplied...
# Render the form with error messages (if any).
return render(request, 'disp_page.html', {'form': form})
Basically the disp_page displays the form. I type the name of a city in the form(EX:NEWYORK) and then it has to redirect to the "geo" function in my views.py which would output the coordinates in a different view. This redirection doesn't seem to be happening. Any help is appreciated!!
change this line
url(r'^disp_page/(?P<city>\w+)/$',views.geo,name='coods'),
in rango/urls.py to :
url(r'^disp_page/(?P<city>\w+)/$',views.geo,name='geo'),
and use :
return HttpResponseRedirect(reverse('rango:geo', args=(city,)))

Django slug changes URL but doesn't get detail view

Building a blog in Django and I suspect something is wrong with matching my main urls.py
from django.conf import settings
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'$', 'posts.views.home'),
url(r'^(?P<slug>[\w-]+)/$', 'posts.views.single'),
)
Here's my views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, RequestContext, Http404, get_object_or_404
from .models import Post
def home(request):
posts = Post.objects.filter(private=False)
return render_to_response('all.html', locals(), context_instance=RequestContext(request))
def single(request, slug):
post = Post.objects.filter(slug=slug)
return render_to_response('single.html', locals(), context_instance=RequestContext(request))
The function-based view home works perfectly and returns all non-private posts. However, the single view alters the URL to make the correct slug (ie: 127.0.0.1/this-correct-slug) but just goes to the top of the page and does nothing to filter the content (shows a 200 GET request in terminal). Using post = get_object_or_404(Post, slug=slug) yields same result.
I'm unsure of the post = Post.objects.filter(slug=slug) part but I also know it's not getting that far - trying to add print statements to see if the function is being called shows nothing.
I'm also a little unsure of the argument locals(). I've been using it but, frankly, only because I'm still not sure how to use the data dictionary.
Assume that the templates all.html and single.html are correct.
Thanks!
The problem is that your first regex is not rooted. It matches '$' which basically means "any string that ends" - which is everything. So all URLs end up being matched by that pattern.
It should be ^$, ie the empty string.

Django - Reusing views in different templates

It's probably a stupid question but its really late here and my brain died after my 6th coffee.
I'm building (or trying to) a simple blogging application that would display an article index on the homepage - aka. recent articles - and on the main blog page. To do so I've managed to scribble out a following view:
def index(request):
'''Article index'''
archive_dates = Article.objects.datetimes('date_publish','month', order='DESC')
categories = Category.objects.all()
page = request.GET.get('page')
article_queryset = Article.objects.all()
paginator = Paginator(article_queryset, 5)
try:
articles = paginator.page(page)
except PageNotAnInteger:
#If page requested is not an integer, return first page.
articles = paginator.page(1)
except EmptyPage:
#If page requested is out of range, deliver last page of results.
articles = paginator.page(paginator.num_pages)
return render(
request,
'blog/article/index.html',
{
'articles': articles,
'archive_dates': archive_dates,
'categories': categories
}
)
However to display the index within two different URLs I've copied the code changing only few variables, ie. name and template to render.
What could I do to render this view within both URLs yet not duplicate it in my views.py?
Am I right in thinking that I'd have to have 3 views, a main one and two sub ones that would import the code from the main one?
Or should I be using a custom template tag instead?
EDIT
As requested, adding urls.py
from django.conf.urls import *
from django.contrib import admin
from settings import MEDIA_ROOT
from django.views.generic import TemplateView
from blog.views import *
admin.autodiscover()
urlpatterns = patterns('',
#Blog URLs
url('^$', home_index, name='blog-preview'),
url('^blog/archive/(?P<year>[\d]+)/(?P<month>[\d]+)/$', date_archive, name='blog-date-archive'),
url('^blog/archive/(?P<slug>[-\w]+)/$', category_archive, name='blog-category-archive'),
url('^blog/categories/', category_list, name='blog-category-list' ),
url('^blog/(?P<slug>[-\w]+)/$', single, name='blog-article-single'),
url('^blog/$', index, name='blog-article-index'),
url(r'^contact/', include("contact_form.urls", namespace="contact_form")),
url(r'^admin/', include(admin.site.urls)),
)
It's very simple: map two urls in your conf to the view like this:
urlpatterns = patterns('',
url(r'first_expression', index, name='first'),
url(r'second_expression', index, name='second'),
)
Also, a little advise on your code: try to avoid wildcard imports. They are dangerous...
Insead use:
from package import MyClass, my_function, my_etc

Categories