I have a URL like this:
url(r'^(?P<user_id>\d+)/profile/$', views.ProfileView.as_view(), name='profile'),
When the user clicks on Update Profile I do the update of form and redirect to the same Profile URL with message using messaging framework.
# views
# Use the message framework to pass the message profile successfully updated
messages.success(request, 'Profile details updated.')
# Redirect to the same view with the profile updated successfully message
return HttpResponseRedirect(reverse('profile', args=(request.user.id,)))
But I get this error:
NoReverseMatch at /5/profile/
Reverse for 'profile' with arguments '(5L,)' and keyword arguments '{}' not found.
What's wrong?
You're getting that because of how Python 2.x.x works.
All integers that comes from a database row will get suffixed with L or l (t commonly the capital L).
One way that'll work quick and dirty is
return HttpResponseRedirect(reverse('profile', args=(int(long(request.user.id)),)))
Related
Ive got a users profile page and an update_profile page.
My projects urls.py:
re_path(r'^profile/(?P<username>[\w-]+)/$', include('users.urls')),
My users.urls:
path('', views.profile, name='profile'),
path('update_profile', views.update_profile, name='update_profile'),
Prior to adding the username argument to the url both of these links were working. Since adding the username argument, I can access the profile page but the update_profile page throws a 404 error. My understanding is that if the address bar reads www.site/profile/testuser/update_profile the projects urls.py will strip the www.site/profile/testuser/ and pass just update_profile to the profile apps urls.py, which then should match the path ive given.
Why isnt this working?
On my profile page I have a check that ensures the username passed in matches the logged in user (so users can only access their own profiles). I will need a similar check on the update_profile page, but currently arent passing username to the update profile page. How could I perform this check without passing it in a second time like /profile/testuser/update_profile/testuser?
Thank you.
These are the answers to your questions:
1. Your url is not working because of there is a $ at the end of users.urls url. $ is a zero width token which means an end in regex. So remove it.
2. You do not need to add <username> at the profile_update url. If you are using UpdateView, then add slug_url_kwarg attribute to UpdateView, like:
class MyUpdateView(UpdateView):
slug_url_kwarg = "username"
If you are using function based view, then simply use:
def myview(request,username):
....
Using the Django registration redux plugin to create a form page after a user has successfully registered for my app. However I keep receiving this error TypeError at /accounts/register/
get_success_url() missing 1 required positional argument: 'user' after completing the registration. It should redirect to a page with a form shown in the method below
from registration.backends.simple.views import RegistrationView
# my new reg view, subclassing RegistrationView from our plugin
class MyRegistrationView(RegistrationView):
def get_success_url(self, request, user):
# the named URL that we want to redirect to after
# successful registration
return ('registration_create_word')
Here is the url path
path('accounts/create_word/', views.create_word, name='registration_create_word'),
I have attempted changing the parameters to just user however i received the same error except it is missing self.
Not sure what I am missing. I found a similar question (How to redirect users to a specific url after registration in django registration?) however i still am receiving errors
any help would be greatly appreciated.
I know there are a few questions on the topic already but I have tried to implement those solutions and could not really solve my problem.
I am talking about social signup with allauth here, and facebook in particular.
DESIRED BEHAVIOR: after facebook signup I want user to go to my url "accounts:welcome", but when they simply login I want them to go to my LOGIN_REDIRECT_URL (which is the site's home page).
After looking here and there this is the code I came up with (writing my custom adapter)
settings.py:
LOGIN_REDIRECT_URL = ("gamestream:home")
SOCIALACCOUNT_ADAPTER = "myproject.users.adapter.MySocialAccountAdapter"
adapter.py:
from django.conf import settings
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
def save_user(self, request, sociallogin, form=None):
print('OK11OK')
super().save_user(request, sociallogin, form=form)
return redirect(reverse('accounts:welcome'))
def get_connect_redirect_url(self, request, socialaccount):
print('OK22OK')
assert is_authenticated(request.user)
url = reverse('accounts:welcome')
return url
Please assume that all links/settings are good as for example the console prints out 'OK11OK' when I create myself as a user via the facebook app. The fact is that the method get_connect_redirect_url never gets triggered as I never read 'OK22OK' on the console.
The user is created and I end up on the home page, which is not what I want.
So I thought that after the save_user method something else gets called as I can tell that I pass through accounts:welcome, but then end up on the home page.
I can tell this because if I return an incorrect url in the save_user method I get an error that is specific to that url on that line.
So, what is wrong here?
I think I might be overriding the wrong method but I have read all the code of the base SocialAccountAdapter and I can't see anything else that would be the right choice.
Just wanted to mention that as I have more control on the normal account signup (not social) I have achieved what I wanted.
Any ideas?
Thanks very much!
I had the same problem too, I found two methods:
METHOD 1
Django doesn't use redirection function of the DefaultSocialAccountAdapter, you'll have to override the get_signup_redirect_url function of DefaultAccountAdapter to achieve the result.
First you need to change the default adapter in settings.py:
ACCOUNT_ADAPTER = 'users.adapter.MyAccountAdapter'
Then, just override the get_signup_redirect_url with your url:
# project/users/adapter.py
from allauth.account.adapter import DefaultAccountAdapter
class MyAccountAdapter(DefaultAccountAdapter):
def get_signup_redirect_url(self, request):
return resolve_url('/your/url/')
METHOD 2
This is the easier one
If you take a look at the source code at DefaultAccountAdapter it says:
Returns the default URL to redirect to after logging in. Note
that URLs passed explicitly (e.g. by passing along a next
GET parameter) take precedence over the value returned here.
So, you can pass along a next parameter in your login template to force the redirection. Here is an example using Google social login:
{% load socialaccount %}
{% providers_media_js %}
{# your html tags #}
<body>
SOCIAL LOGIN
</body>
Of course you can personalize the next url (I'm refering to /success/url/) as you wish. You can pass a context variable with your desired url and put it there instead of that hardcoded url.
Say, in the post method of my registration class, I want to redirect the user to the login page if the user is already registered, simple enough.
class Register(View):
...
def post(self, request):
# Some code to check if the email address is already in the db
message = {'message': 'You are already a member and registered the project. Please just log-in',
'registration_date': the_registered_date}# The form with the filled-in data is returned
return HttpResponseRedirect(reverse('accounts:login', kwargs = message))
in my urls.py:
#urls.py
...
url(r'^login/{0,1}$', Login.as_view(), name='login', kwargs={'message': None, 'date': None}),
This gives me the error message:
Reverse for 'login' with arguments '()' and keyword arguments '{'message': 'You are already a member and registered the project. Please just log-in', 'registration_date': datetime.datetime(2015, 10, 15, 14, 3, 39, 864000, tzinfo=<UTC>)}' not found. 2 pattern(s) tried: [u'accounts/$', u'accounts/login/{0,1}$']
What am I doing wrong?
Your url definition is wrong, also sounds like your misunderstood what kwargs does in reverse. It feeds the named arguments of your url definition with it's value, not passing context to the view.
For example, you could do this:
url(r'test_suite/(?P<test_name>\w+)/(?P<test_id>\d+)$', 'test', name='test')
reverse('test', kwargs={'test_name': 'haha', 'test_id': 1})
kwargs will substitute your test_name in url definition with haha and test_id with 1. This will produce a url: test_suite/haha/1.
Kwargs in reverse are the variables that go into your URL to make it unique. It would be really odd to see a message/date inside a URL...which is what your URLconf is trying to do.
Also, you can't redirect with context in Django without going to trouble that makes the juice not worth the squeeze. One option is to use the messages framework to display a message on the login page if you want to do that after the redirect.
My solution would be to remove the kwargs from your URLConf for /login/ and use the messages framework (or sessions) to pass the information to the login page after the redirect.
I'm working on my first django application, and I can't find anything in the docs that explains this.
I have a view called submit_proposal. If successful, it stores the relevant objects to the database then sends a user to a listing of all their open proposals. It displays correctly, but the listing page URL isn't shown by the browser.
Here's the code:
context = RequestContext(request,
dict(user_name=gc_user.get_full_name,
game_list=game_list,
POSTData=request.POST,
)
)
template = loader.get_template('user_proposals.html')
return HttpResponse(template.render(context))
This is called from submit_proposal, which passes the returned HttpResponse object back in turn:
result = user_proposals(request)
return result
I've looked at result in the debugger, and as far as I can tell it doesn't include a URL generated from the template name. Should I be doing something else to create the response? Or do I need to use something other than HttpResponse?
Thanks for your help!
Beverly
The most common way to do this in Django is to have two urls, for instance:
urlpatterns = patterns('',
url(r'^proposal/$', 'app.views.submit_proposal', name='submit_proposal'),
url(r'^proposal/all/$', 'app.views.list_proposals', name='list_proposals'),
Then the submit_proposal function should validate, store and redirect the user to list_proposals if successful
from django.shortcuts import redirect
def submit_proposal(request):
...
return redirect('list_proposals')
The argument to redirect is the name of the url for listing proposals.