How to change the value of activate_url in django allauth? - python

I am using allauth and after registration the user receives an email asking them to click a link to verify their email address. I would like to change the value of this link.
I would like to change it from
http://localhost:8001/account/confirm-email/hy72ozw8b1cexuw2dsx4wwrmgzbmnyxx4clswh67tcvgyovg/
to
http://localhost:8001/index.html#/verifyEmail/hy72ozw8b1cexuw2dsx4wwrmgzbmnyxx4clswh67tcvgyovg/
How can I do this? I see that activate_url value is being used in email_confirmation_text.txt

You don't really have to override allauth's urls.py in order to achieve this, all you need to do is specify your version of url after including allauth's urls:
from django.conf.urls import patterns, include, url
from allauth.account.views import confirm_email
urlpatterns = patterns('',
...
url(r'^accounts/', include('allauth.account.urls')),
url(r'^index.html#/verifyEmail/(?P<key>\w+)/$', confirm_email,
name="account_confirm_email"),
# but I would recommend changing that url:
url(r'^verify-email/(?P<key>\w+)/$', confirm_email,
name="account_confirm_email"),
...
)
Here is a nice article about URLS: Cool URIs don't change

I have not used django-allauth or incorporated it into one of my projects, but just poking around in their source code tells me the following:
The send method just does a basic urlresolvers.reverse call, which means it's constructing the URL from account/urls.py as defined here.
As such, you have three options:
Overwrite their urls.py which you will have to repeat each time you update the package (yuck).
Raise an issue on their GitHub and see if they will add this as a configuration option rather than "hard-coding" it which they have done.
Try to subclass their EmailConfirmation model, overriding their send method with something more appropriate for your project, and see if you can get it to use yours instead of theirs (no idea if this is workable or not).

Related

Django two-factor authentication, require 2FA on specific views

I am implementing Django two-factor-auth on my website and I would love to have some views protected by two-FA, and some other not.
In order to do so, I use the decorator #otp_required which works great, but unfortunately asks the users to input their credentials again (to handle user sessions, I use the registration module).
Would you be able to give me a good to way to hack the form in order to just ask the user to input the token (skipping a step of the form, basically) ?
Thanks a lot,
For those who care, I found a way to do it that is quite clean.
The trick was to override the LoginView class in the core.py module of the two_factor_authentication module.
In order to do so, go to your views and insert the following code:
class CustomLoginView(LoginView):
form_list = (
('token', AuthenticationTokenForm),
('backup', BackupTokenForm),
)
def get_user(self):
self.request.user.backend = 'django.contrib.auth.backends.ModelBackend'
return self.request.user
Basically, I erase the 'auth' step and override the method get_user() in order to return the current user.
The backend must be specified otherwise Django raises an error.
Now, to make that class be used instead of the LoginView, go to your urls and insert the following line BEFORE including the two_factor.urls.
url(r'^account/login/$', tradingviews.CustomLoginView.as_view(), name='login'),
That's it!

How can I redirect in django middleware? global name 'view' is not defined

Django newbie here, need help on basic middleware to redirect to another view if a certain model field is empty.
I am creating a terms of agreement page that users must get redirected to right after they signup to the platform if their filed_terms field on their Profile model is empty.
I am using middleware for this. However I am unable to get this to work. This is my middleware class:
class TermsMiddleware(object):
def process_request(self, request):
if request.user.profile.filled_terms is None:
return redirect(reverse(terms))
This gives me the following error:
global name 'terms' is not defined
I also have the url matcher that works perfectly when I navigate to it manually:
url(r'^terms/', 'my_app.views.terms')
I have a terms.html template and a terms view in my views.py file that is working perfectly in all other respects. I have also added it to the settings middleware requirements to make sure it loads.
Do I have to import something from views or url dispatcher into my middleware file? If so what would that be? I have been at this for a while an cannot find anything helpful.
reverse function takes url name instead on the regex. So you need to add name on your url configuration. Here is the example.
url(r'^terms/', 'my_app.views.terms', name='terms')
Add this in your views.py
from django.core.urlresolvers import reverse
And you need to fix your reverse function into.
return redirect(reverse('terms'))
Python interpret your terms as a variable and you have no variable named terms while you need to put string on reverse.

django-stronghold not using next parameter for redirecting

I'm not sure whether this is a problem with django-stronghold or with django itself.
What happens:
Calling any front end URL (e.g. http://www.myapp.com/careers) leads me to the login page
The URL shown looks like this: http://www.myapp.com/accounts/login/?next=/careers
Upon login, I am forwarded to the admin interface (like when logging in at http://www.myapp.com/admin)
The displayed URL is still http://www.myapp.com/accounts/login/?next=/careers
What I want:
Upon login, I want to be forwarded to the URL called originally, as correctly stored in the next parameter (in the example: http://www.myapp.com/careers)
My setup:
I'm using Django 1.6.
As suggested in the docs, I have installed django-stronghold via pip and activated it in my project like so:
INSTALLED_APPS = (
...
'stronghold', # last entry
)
MIDDLEWARE_CLASSES = [
...
'stronghold.middleware.LoginRequiredMiddleware', # last entry
]
At first, I ran into a redirect loop, so I defined the STRONGHOLD_PUBLIC_URLS:
STRONGHOLD_PUBLIC_URLS = (
r'^/admin.*?$', # Don't touch the admin pages
r'^/accounts/login/$', # Avoid redirect loop
)
What I tried:
Explicitly setting LOGIN_URL and LOGIN_REDIRECT_URL, as suggested here - didn't help.
In the context of logging into the admin interface, django's login mechanism works fine, just like it is documented here:
Here’s what django.contrib.auth.views.login does:
If called via GET, it displays a login form that POSTs to the same URL. [...]
If called via POST with user submitted credentials, it tries to log the user in. If login is successful, the view redirects to the URL specified in next. [...]
If I call an admin URL other than .../admin (e.g. http://www.myapp.com/admin/myapp_base/event/), the displayed URL remains the same while the login form is shown (no next parameter). After logging in, I see the requested page.
Ideas?
Any ideas why the redirect isn't working for the front end URLs?

Django: Getting list of all URL regexes [duplicate]

Is there a way to get the complete django url configuration?
For example Django's debugging 404 page does not show included url configs, so this is not the complete configuration.
Django extensions provides a utility to do this as a manage.py command.
pip install django-extensions
Then add django_extensions to your INSTALLED_APPS in settings.py. then from the console just type the following
python manage.py show_urls
Django is Python, so introspection is your friend.
In the shell, import urls. By looping through urls.urlpatterns, and drilling down through as many layers of included url configurations as possible, you can build the complete url configuration.
import urls
urls.urlpatterns
The list urls.urlpatterns contains RegexURLPattern and RegexURLResolver objects.
For a RegexURLPattern object p you can display the regular expression with
p.regex.pattern
For a RegexURLResolver object q, which represents an included url configuration, you can display the first part of the regular expression with
q.regex.pattern
Then use
q.url_patterns
which will return a further list of RegexURLResolver and RegexURLPattern objects.
At the risk of adding a "me too" answer, I am posting a modified version of the above submitted script that gives you a view listing all the URLs in the project, somewhat prettified and sorted alphabetically, and the views that they call. More of a developer tool than a production page.
def all_urls_view(request):
from your_site.urls import urlpatterns #this import should be inside the function to avoid an import loop
nice_urls = get_urls(urlpatterns) #build the list of urls recursively and then sort it alphabetically
return render(request, "yourapp/links.html", {"links":nice_urls})
def get_urls(raw_urls, nice_urls=[], urlbase=''):
'''Recursively builds a list of all the urls in the current project and the name of their associated view'''
from operator import itemgetter
for entry in raw_urls:
fullurl = (urlbase + entry.regex.pattern).replace('^','')
if entry.callback: #if it points to a view
viewname = entry.callback.func_name
nice_urls.append({"pattern": fullurl,
"location": viewname})
else: #if it points to another urlconf, recur!
get_urls(entry.url_patterns, nice_urls, fullurl)
nice_urls = sorted(nice_urls, key=itemgetter('pattern')) #sort alphabetically
return nice_urls
and the template:
<ul>
{% for link in links %}
<li>
{{link.pattern}} ----- {{link.location}}
</li>
{% endfor%}
</ul>
If you wanted to get real fancy you could render the list with input boxes for any of the regexes that take variables to pass to the view (again as a developer tool rather than production page).
This question is a bit old, but I ran into the same problem and I thought I would discuss my solution. A given Django project obviously needs a means of knowing about all its URLs and needs to be able to do a couple things:
map from a url -> view
map from a named url -> url (then 1 is used to get the view)
map from a view name -> url (then 1 is used to get the view)
Django accomplishes this mostly through an object called a RegexURLResolver.
RegexURLResolver.resolve (map from a url -> view)
RegexURLResolver.reverse
You can get your hands on one of these objects the following way:
from my_proj import urls
from django.core.urlresolvers import get_resolver
resolver = get_resolver(urls)
Then, you can simply print out your urls the following way:
for view, regexes in resolver.reverse_dict.iteritems():
print "%s: %s" % (view, regexes)
That said, Alasdair's solution is perfectly fine and has some advantages, as it prints out some what more nicely than this method. But knowing about and getting your hands on a RegexURLResolver object is something nice to know about, especially if you are interested in Django internals.
The easiest way to get a complete list of registered URLs is to install contrib.admindocs then check the "Views" section. Very easy to set up, and also gives you fully browsable docs on all of your template tags, models, etc.
I have submitted a package (django-showurls) that adds this functionality to any Django project, it's a simple new management command that integrates well with manage.py:
$ python manage.py showurls
^admin/
^$
^login/$
^logout/$
.. etc ..
You can install it through pip:
pip install django-showurls
And then add it to your installed apps in your Django project settings.py file:
INSTALLED_APPS = [
..
'django_showurls',
..
]
And you're ready to go.
More info here -
https://github.com/Niklas9/django-showurls
If you want a list of all the urls in your project, first you need to install django-extensions
You can simply install using command.
pip install django-extensions
For more information related to package goto django-extensions
After that, add django_extensions in INSTALLED_APPS in your settings.py file like this:
INSTALLED_APPS = (
...
'django_extensions',
...
)
urls.py example:
from django.urls import path, include
from . import views
from . import health_views
urlpatterns = [
path('get_url_info', views.get_url_func),
path('health', health_views.service_health_check),
path('service-session/status', views.service_session_status)
]
And then, run any of the command in your terminal
python manage.py show_urls
or
./manage.py show_urls
Sample output example based on config urls.py:
/get_url_info django_app.views.get_url_func
/health django_app.health_views.service_health_check
/service-session/status django_app.views.service_session_status
For more information you can check the documentation.
Are you looking for the urls evaluated or not evaluated as shown in the DEBUG mode? For evaluated, django.contrib.sitemaps can help you there, otherwise it might involve some reverse engineering with Django's code.
When I tried the other answers here, I got this error:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
It looks like the problem comes from using django.contrib.admin.autodiscover() in my urls.py, so I can either comment that out, or load Django properly before dumping the URL's. Of course if I want to see the admin URL's in the mapping, I can't comment them out.
The way I found was to create a custom management command that dumps the urls.
# install this file in mysite/myapp/management/commands/urldump.py
from django.core.management.base import BaseCommand
from kive import urls
class Command(BaseCommand):
help = "Dumps all URL's."
def handle(self, *args, **options):
self.show_urls(urls.urlpatterns)
def show_urls(self, urllist, depth=0):
for entry in urllist:
print ' '.join((" " * depth, entry.regex.pattern,
entry.callback and entry.callback.__module__ or '',
entry.callback and entry.callback.func_name or ''))
if hasattr(entry, 'url_patterns'):
self.show_urls(entry.url_patterns, depth + 1)
If you are running Django in debug mode (have DEBUG = True in your settings) and then type a non-existent URL you will get an error page listing the complete URL configuration.

How to do reverse URL search in Django namespaced reusable application

Consider that I include namespaced reusable application:
urlpatterns = patterns('',
# ella urls
url('^ella/', include('ella.core.urls', namespace="ella")),
)
Now, the Ella applications has urls like that:
urlpatterns = patterns( '',
url( r'^(?P<category>[a-z0-9-/]+)/$', category_detail, name="category_detail" ),
# object detail
url( r'^(?P<category>[a-z0-9-/]+)/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<content_type>[a-z0-9-]+)/(?P<slug>[a-z0-9-]+)/$',
object_detail, name="object_detail" )
)
Now, calling {% url ella:category_detail category="cat" %} works fine. However, when object tries to generate link to it's details, it calls
from django.core.urlresolvers import reverse
url = reverse('object_detail', kwargs={'required' : 'params'})
This is not working, unless rewritten as
from django.core.urlresolvers import reverse
url = reverse('ella:object_detail', kwargs={'required' : 'params'})
So, if I understand it correctly, including reusable application into namespace breaks all inner reverse()s inside given application.
Is it true? What have I missed? Is there any way around?
Since you have name-spaced url configuration, you need to mention namespace:view-name pattern in order to reverse it properly (especially from view).
But, if you want to avoid this, you may also pass namespace/appname as current_app parameter.
There are multiple ways to specify current_app when you are in template. But if you are in view, you need to hard-code as you did, or pass to current_app parameter
url = reverse('object_detail',
kwargs={'foo':'bar'},
current_app=app_name_or_name_space)
refer: http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
URL Namespaces can be specified in two ways.
Firstly, you can provide the application and instance namespace as arguments to include() when you construct your URL patterns. For example,:
(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
This is right from http://docs.djangoproject.com/en/dev/topics/http/urls/#defining-url-namespaces.
Try changing include('ella.core.urls', namespace="ella") to include('ella.core.urls', namespace="ella", app_name="ella"). I'm not 100% this will work, but its worth a shot.
At least in Django 1.8 you can write something like this:
url = reverse('%s:object_detail' % request.resolver_match.namespace, kwargs={'required' : 'params'})
request.resolver_match.namespace is a string containing the namespace of the currently running view.

Categories

Resources