A solution: Found the following django snippet that seems to work fine
(http://djangosnippets.org/snippets/2445/)
from django.utils.functional import lazy
from django.core.urlresolvers import reverse
#Workaround for using reverse with success_url in class based generic views
#because direct usage of it throws an exception.
reverse_lazy = lambda name=None, *args : lazy(reverse, str)(name, args=args)
Apparently, there is now a reverse_lazy function in django trunk.
Update: This error has something to do with me making a call to reverse inside a generic view:
class AddObjView(CreateView):
form_class = ObjForm
template_name = 'manager/obj_add.html'
success_url = reverse('manager-personal_objs')
Is this not valid?
If I instead of generic write something like this, it works:
def add_obj(request, pk):
a=reverse('manager-personal-objs')
return HttpResponse(a)
I have a project with 2 apps in it. Each app has its urls and views. They both work fine, but on the manager app, as soon as I reference the reverse function in the views(any view), I get the following error:
Exception Type: ImproperlyConfigured
Exception Value: The included urlconf manager.urls doesn't have any patterns in it
The urls file:
urlpatterns = patterns('',
url(r'^$', ObjView.as_view(), name='manager-obj'),
url(r'^add/$', AddObjView.as_view(), name='manager-add_obj'),
url(r'^personal/$', PersonalObjsView.as_view(), name='manager-personal_objs'),
)
Exception Location: ...site-packages\django\core\urlresolvers.py in _get_url_patterns, line 283
I get this error in the entire site(edit: this apparently happens because an attempt to import the manager.urls will result in the error). If I remove the include manager.urls, everything goes back to work; if I remove the call to reverse, everything is fine; if I try to rewrite manager.urls to a simpler version, it continues with the error.
I've been over this many times, can't seem to find anything wrong.
edit:root urls.py
# coding=utf8
from django.conf.urls.defaults import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.views.generic.simple import direct_to_template
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Uncomment the admin/doc line below to enable admin documentation:
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
# Home Page
url(r'^$', direct_to_template, {'template': 'home.html'}, name="home"),
# manager
url(r'^manager/', include('manager.urls')),
# writing
url(r'^writing/', include('writing.urls')),
)
urlpatterns += staticfiles_urlpatterns()
edit2: Should also be noted that the url template tag works fine in the manager app and the reverse call works if I do it on the other app.
Also, every url has a written working view.
The problem is that your URLConf hasn't finished loading before your class based view attempts to reverse the URL (AddObjView.success_url). You have two options if you want to continue using reverse in your class based views:
a) You can create a get_success_url() method to your class and do the reverse from there
class AddObjView(CreateView):
form_class = ObjForm
template_name = 'manager/obj_add.html'
def get_success_url():
return reverse('manager-personal_objs')
b) If you are running on the trunk/dev version of Django, then you can use reverse_lazy https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy
from django.core.urlresolvers import reverse_lazy
class AddObjView(CreateView):
form_class = ObjForm
template_name = 'manager/obj_add.html'
success_url = reverse_lazy('manager-personal_objs')
Option "b" is the preferred method of doing this in future versions of Django.
Related
Just started with TastyPie to expose the data. Trying to tie together resources using tastypie.Api for urls.py.
But I get this error when I try to access them through localhost:api/**resource.
my api.py:
from tastypie.resources import ModelResource
from idg.models.molecule_dictionary import MoleculeDictionary
class MoleculeDictionaryResource(ModelResource):
class Meta:
queryset = MoleculeDictionary.objects.all()
# resource_name = 'moleculedictionary'
my url.py:
from django.conf.urls import url, include, patterns
from idg.api import MoleculeDictionaryResource
from django.contrib import admin
from tastypie.api import Api
from . import views
dictionary_resource = MoleculeDictionaryResource()
# private_api = Api(api_name='private')
# private_api.register(MoleculeDictionaryResource(), canonical=True)
urlpatterns = [
url(r'^$', views.index, name='index'),
# url(r'^exports/', include('data_exports.urls', namespace='data_exports')),
url(r'^api/', include(dictionary_resource.urls)),
]
Error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/api/moleculedictionary/?format=json
Using the URLconf defined in django_root.urls, Django tried these URL patterns, in this order:
^__debug__/
xadmin/
^idg/
^comments/
^admin/
The current URL, api/moleculedictionary/, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Any suggestions ? I am not sure where I made a mistake. I have followed the tutorial (https://django-tastypie.readthedocs.org/en/latest/tutorial.html)
Uncomment line
resource_name = 'moleculedictionary'
in Your api.py file.
Try this:
private_api = Api(api_name='v1')
private_api.register(MoleculeDictionaryResource(), canonical=True)
url(r'^api/', include(private_api.urls)),
Then you should be able to access it with /api/v1/
I get this error:
The included urlconf 'fouraxis.urls' does not appear to have any
patterns in it. If you see valid patterns in the file then the issue
is probably caused by a circular import.
I know the url pattern has something in it, it looks like this:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^perfil/', include('clientes.urls'), namespace="cliente"),
url(r'^admin/', include(admin.site.urls))
]
clientes.urls:
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from clientes import views
urlpatterns = [
# login
url(r'^login/$', auth_views.login, {'template_name': 'perfiles/login.html'}, name="login"),
url(r'^logout/$', auth_views.logout, {'template_name': 'perfiles/logged_out.html'}, name="login"),
url(r'^mi_perfil/$', views.mi_perfil, name="mi_perfil"),
url(r'^registro_usuario/$', views.RegistroUsuario.as_view(), name="registro_usuario")
]
The RegistroUsuario view looks like this:
class RegistroUsuario(FormView):
template_name = "perfiles/registro_usuario.html"
form_class = UserCreationForm
success_url = reverse("cliente:mi_perfil") # THIS REVERSE
def form_valid(self, form):
return redirect("cliente:mi_perfil")
context = {'form': UserCreationForm}
I understand I can replace the reverse with a plain-text url like this perfil/mi_perfil. But, I want to know why is this happening with reverse, I can't find the explanation on de docs. Also, using reverse is better cause it is dynamic (if anytime I change the url, it still works as long as it keeps its name).
The reverse() call is made when the view is imported, which is probably when the urlconf is first loaded. You need to use reverse_lazy() instead:
from django.core.urlresolvers import reverse_lazy
class RegistroUsuario(FormView):
template_name = "perfiles/registro_usuario.html"
form_class = UserCreationForm
success_url = reverse_lazy("cliente:mi_perfil") # THIS REVERSE
def form_valid(self, form):
return redirect("cliente:mi_perfil")
context = {'form': UserCreationForm}
I'm trying to change my project to use class based views, and I'm running into a strange error with my url conf
I have a classed based view:
class GroupOrTeamCreate(AjaxableResponseMixin, CreateView):
model = GroupOrTeam
fields = ['name', 'description']
#success_url = reverse('home_page') # redirect to self
I have the last line commented out because if I don't, django complains that there are no patterns in my url conf.
To start, here's my base urls.py
urlpatterns = patterns('',
url(r'^$', TemplateView.as_view(template_name='core/home.html'), name='home_page'),
url(r'^administration/', include('administration.urls', app_name='administration')),
url(r'^reports/', include('reports.urls', app_name='reports')),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
)
Clearly there are patterns in there. If I comment out the administration urls, it works. So I assume the problem is in there somewhere.
administration urls.py
from django.conf.urls import patterns, url
from .views import ActiveTabTemplateView, GroupOrTeamCreate, GroupOrTeamUpdate
urlpatterns = patterns('',
# Add page
url(r'^add/$', ActiveTabTemplateView.as_view(template_name='administration/add.html'), name='add_page'),
url(r'^add/(?P<active_tab>\w+)/$', ActiveTabTemplateView.as_view(template_name='administration/add.html'),
name='add_page'),
# Seach page
url(r'^search/$', ActiveTabTemplateView.as_view(template_name='administration/search.html'), name='search_page'),
url(r'^search/(?P<active_tab>\w+)/$', ActiveTabTemplateView.as_view(template_name='administration/search.html'),
name='search_page'),
#--------------------------------------------------------------------------
# Forms
#--------------------------------------------------------------------------
# Groups and teams
url(r'^group-or-team-form/$', GroupOrTeamCreate.as_view(template_name='administration/forms/groups_form.html'),
name='group_or_team_form'),
url(r'^group-or-team-form/(?P<pk>\d+)/$',
GroupOrTeamUpdate.as_view(template_name='administration/forms/groups_form.html'),
name='group_or_team_form'),
)
I'm not seeing the problem.. these pages load just fine without that reverse statement in, it appears to be the introduction of the reverse statement that breaks everything but I can't for the life of me work out what the cause is.
You get the error because the URL conf has not been loaded yet when the class is defined.
Use reverse_lazy instead of reverse.
from django.core.urlresolvers import reverse_lazy
success_url = reverse_lazy('home_page')
So I am using django-registration app to implement a user registration page for my site. I used Django's backends.simple views which allows the users to immediately login after registration. My question is how do I redirect them to my other app's page located in the same directory as the project.
Here is what my main urls.py looks like:
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('',
url(r'^accounts/', include('registration.backends.simple.urls')),
url(r'^upload/', include('mysite.fileupload.urls')),
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^mysite/', include('mysite.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# url(r'^admin/', include(admin.site.urls)),
)
import os
urlpatterns += patterns('',
(r'^media/(.*)$', 'django.views.static.serve', {'document_root': os.path.join(os.path.abspath(os.path.dirname(__file__)), 'media')}),
)
fileupload is the name of the other app I have in the project directory mysite.
This is what the backends.simple.urls looks like:
"""
URLconf for registration and activation, using django-registration's
one-step backend.
If the default behavior of these views is acceptable to you, simply
use a line like this in your root URLconf to set up the default URLs
for registration::
(r'^accounts/', include('registration.backends.simple.urls')),
This will also automatically set up the views in
``django.contrib.auth`` at sensible default locations.
If you'd like to customize registration behavior, feel free to set up
your own URL patterns for these views instead.
"""
from django.conf.urls import include
from django.conf.urls import patterns
from django.conf.urls import url
from django.views.generic.base import TemplateView
from registration.backends.simple.views import RegistrationView
urlpatterns = patterns('',
url(r'^register/$',
RegistrationView.as_view(),
name='registration_register'),
url(r'^register/closed/$',
TemplateView.as_view(template_name='registration/registration_closed.html'),
name='registration_disallowed'),
(r'', include('registration.auth_urls')),
)
And here is the backends.simple.views:
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth import login
from django.contrib.auth.models import User
from registration import signals
from registration.views import RegistrationView as BaseRegistrationView
class RegistrationView(BaseRegistrationView):
"""
A registration backend which implements the simplest possible
workflow: a user supplies a username, email address and password
(the bare minimum for a useful account), and is immediately signed
up and logged in).
"""
def register(self, request, **cleaned_data):
username, email, password = cleaned_data['username'], cleaned_data['email'], cleaned_data['password1']
User.objects.create_user(username, email, password)
new_user = authenticate(username=username, password=password)
login(request, new_user)
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=request)
return new_user
def registration_allowed(self, request):
"""
Indicate whether account registration is currently permitted,
based on the value of the setting ``REGISTRATION_OPEN``. This
is determined as follows:
* If ``REGISTRATION_OPEN`` is not specified in settings, or is
set to ``True``, registration is permitted.
* If ``REGISTRATION_OPEN`` is both specified and set to
``False``, registration is not permitted.
"""
return getattr(settings, 'REGISTRATION_OPEN', True)
def get_success_url(self, request, user):
return (user.get_absolute_url(), (), {})
I tried the changing the get_success_url function to just return the url I want which is /upload/new but it still redirected me to users/insert username page and gave an error. How do I redirect the user to the upload/new page where the other app resides after registration?
Don't change the code in the registration module. Instead, subclass the RegistrationView, and override the get_success_url method to return the url you want.
from registration.backends.simple.views import RegistrationView
class MyRegistrationView(RegistrationView):
def get_success_url(self, request, user):
return "/upload/new"
Then include your custom registration view in your main urls.py, instead of including the simple backend urls.
urlpatterns = [
# your custom registration view
url(r'^register/$', MyRegistrationView.as_view(), name='registration_register'),
# the rest of the views from the simple backend
url(r'^register/closed/$', TemplateView.as_view(template_name='registration/registration_closed.html'),
name='registration_disallowed'),
url(r'', include('registration.auth_urls')),
]
I am using django_registration 3.1 package. I have posted all 3 files (views.py urls.py forms.py) that are needed to use this package.
To redirect user to a custom url on successfull registration, create a view that subclasses RegistrationView. Pass in a success_url of your choice.
Views.py:
from django_registration.backends.one_step.views import RegistrationView
from django.urls import reverse_lazy
class MyRegistrationView(RegistrationView):
success_url = reverse_lazy('homepage:homepage') # using reverse() will give error
urls.py:
from django.urls import path, include
from django_registration.backends.one_step.views import RegistrationView
from core.forms import CustomUserForm
from .views import MyRegistrationView
app_name = 'core'
urlpatterns = [
# login using rest api
path('api/', include('core.api.urls')),
# register for our custom class
path('auth/register/', MyRegistrationView.as_view(
form_class=CustomUserForm
), name='django_registration_register'),
path('auth/', include('django_registration.backends.one_step.urls')),
path('auth/', include('django.contrib.auth.urls'))
]
forms.py:
from django_registration.forms import RegistrationForm
from core.models import CustomUser
class CustomUserForm(RegistrationForm):
class Meta(RegistrationForm.Meta):
model = CustomUser
You can set SIMPLE_BACKEND_REDIRECT_URL in settings.py.
settings.py
SIMPLE_BACKEND_REDIRECT_URL = '/upload/new'
If you wish, you can modify the following file /usr/local/lib/python2.7/dist-packages/registration/backends/simple/urls.py, changing the path, for example:
Before modifying:
success_url = getattr (settings, 'SIMPLE_BACKEND_REDIRECT_URL', '/'),
After modifying:
success_url = getattr (settings, 'SIMPLE_BACKEND_REDIRECT_URL', '/upload/new'),
Regards.
Diego
I've been working my way through the tutorials and thought that I'd understood the MVC framework. I have three models, two of which (Guests, Bookings) are populated. I can call data from Guests no problem. I tried to call data from Bookings and get ViewDoesNotExist at /bookings Tried booked_dates in module views. Error was: 'module' object has no attribute 'booked_dates'.
My urls are:
from django.conf.urls.defaults import *
#from views import current_datetime, people, detail, booked_dates
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('views',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^mysite/', include('mysite.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
url(r'^time/$','current_datetime'),
url(r'^mariners/$','people'),
url(r'^mariners/(?P<guest_id>\d+)/$','detail'),
url(r'^bookings/$','booked_dates'),
)
The views are:
from django.shortcuts import get_object_or_404, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext
from guests.models import Guest, Booking, Price
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return render_to_response('current_datetime.html', {'current_date': now})
def people(request):
guests_all = Guest.objects.all().order_by('last_name')
return render_to_response('guests_all.html', {'guests_all': guests_all})
def detail(request, guest_id):
g = get_object_or_404(Guest, pk=guest_id)
return render_to_response('guest_detail.html', {'detail' : g})
def booked_dates(request):
dates_all = Booking.objects.all().order_by('start_date')
return render_to_response('bookings.html', {'dates_all' : dates_all})
I haven't included the Models, but Booking is the correct class name, and start_date and end_date are correct.
I can't see an exact replica of this problem, and have tried numerous things to correct it, including a simple 'hello world' view, but I get the same error message.
I must be doing something wrong, but can't see what it might be. I've tried calling the views in a shell, which works.
Thanks for your help.
try including the app name with the view not just the view function
url(r'^bookings/$','guests.views.booked_dates'),