I have experienced using reverse within get_absolute_url method in the model, but I wish I have an idea about the difference between reverse and redirect, I have tried to search on google about it but there is almost nothing
I don't know what should I write also to convince stack overflow that I don't have any other description
Reverse and redirect have a different meaning. Here is a simple explanation:
reverse in Django is used to find the URL of a given resource. Let's say that you have a blog website and from the main page, you want to provide links to your blog posts. You can of course just hard-code /posts/123/ and just change the ID of your blog post in URL, but that makes it hard to change your URL for the post in the future. That's why Django comes with reverse function. All you need to do is to pass the name of your URL path (defined in your urlpatterns) and Django will find for you the correct URL. It is called reverse because it is a reverse process of determining which view should be called for a given URL (which process is called resolving).
Redirects are not specific to Django or any other web frameworks. Redirect means that for a given URL (or action), the user should be instructed to visit a specific URL. This can be done by sending a special redirect request and from there the browser will handle it for the user, so no user action is required in that process. You can use reverse in redirect process to determine the URL that the user should be redirected to.
GwynBleidD has given you the answer, but there is a reason why you might be getting confused. The Django redirect shortcut accepts arguments in several different forms. One of them is a URLpattern mane, with arguments, that is then passed to reverse to generate the actual URL to redirect to. But that's just a shortcut, to enable a common pattern.
here's an example
app/views
#imports
def indexView(request):
....
return render(request, 'index.html', context)
def loginView(request):
....
return redirect('index')
def articleDetailView(request, id):
....
return redirect(reverse('article-comments', kwargs={'id':id})
def articleCommentsView(request, id):
....
return render(request, 'comment_list.html', context)
proj/urls
#imports
urlpatterns = [
....,
path('', include(app.urls))
]
app/urls
#imports
urlpatterns = [
....,
path('index/', index, name='index'),
path('login/', loginView, name='login'),
path('article/<int:id>/detail', articleDetailView, name='article-detail'),
path('article/<int:id>/comments/',articleCommentsView, name='article-comments')
....,
]
For loginView redirect will return url as-is i.e. 'index' which will be appended to base(project) urlpatterns. Here redirect(reverse('index')) will also work since kwargs is None by default for reverse function and 'index' view doesn't require any kwarg. It returns '/index/' which is passed to redirect(which again will be appended to base urls).
One thing to note is that reverse is used to make complete url - needed for redirect - that is shown in 'articleDetailview'.
The most basic difference between the two is :
Redirect Method will redirect you to a specific route in General.
Reverse Method will return the complete URL to that route as a String.
Related
I am struggling with a basic redirect functionality.
I need to redirect all traffic not matching certain paths to another domain.
in my urls.py
re_path(r'^(?P<shortcode>[\w-]+)/$', core_views.myView)
and the corresponding function in views.py
def myView(request, shortcode=None):
url = 'www.newdomain.cz/' + str(shortcode)
return HttpResponsePermanentRedirect(url)
but what it does is - when called for example www.olddomain.com/sdfasd it redirects me to www.olddomain.com/sdfasd/www.newdomain.cz/sdfasd but I obviously need only www.newdomain.cz/sdfasd
what am I missing?
You need to use a fully qualified url.
def myView(request, shortcode=None):
url = 'http://www.newdomain.cz/' + str(shortcode)
See the doc here.
the redirect url is
"liveinterviewList/2"
and, ofcourse, I declare that url in url.py
more over, when I type that url in browser manualy, it works well.
what's the matter?
more question.
at this case, I write the user_id on the url.
I think, it is not good way to make url pattern.
but I don't know how I deliver the user_id variable without url pattern.
please give me a hint.
What HariHaraSudhan left out was how to use parameters. For your case, you would want something like:
path(r'liveinterviewList/<int:userId>', ..., name='live-interview'),
And then when you are ready to reverse, use this:
reverse('app:live-interview', kwargs={ 'userId': userId })
where app is the name of the app in which your view lives. If your url lives in the main urls file , you don't need the app: prefix.
Django reverse function accepts the name of the path not the URL.
lets say i have url patterns like this
urlpatterns = [
path('/users/list', name="users-list")
]
In my view i can use like this
def my_view(request):
return redirect(reverse("users-list"));
You should add a name to your path url and use it to redirect.
As the django doc says :
urls :
urlpatterns = [
path('/name', name="some-view-name")
]
def my_view(request):
...
return redirect('some-view-name')
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.
My Django project "animals" has an app called "birds". In animals/urls.py the "birds" URIs are routed to birds/urls.py like this:
urlpatterns=[
url(r'^birds/', include('birds.urls')),
url(r'^b/', include('birds.urls')), # alias
]
The "birds/" is the official, permanent base URI; "b/" is accepted as a shortcut/alias.
How can I have the "b/" URIs (permanently) redirected to "birds/", such that even though users can enter "b/penguin", the address bar of the browser will (ultimately) show "birds/penguin"? I prefer not to touch any code in the "birds" app, because it should not know (care) how the project maps URIs to the app.
I have tried to use
RedirectView.as_view(pattern_name='birds'))
but this results in a 410 Gone response. And
RedirectView.as_view(url='/birds/'))
redirects /b/penguin to /birds/, killing my bird.
You should try something like that:
from django.views.generic import RedirectView
urlpatterns=[
url(r'^birds/', include('birds.urls')),
url(r'^b/(?P<path>.*)$', RedirectView.as_view(url='/birds/%(path)s')),
]
You can make a custom middleware to handle the redirects for you
class BirdMiddleware(MiddlewareMixin, object):
def process_view(self, request, view_func, view_args, view_kwargs):
if '/b/' in request.path:
return HttpResponseRedirect(request.path.replace('/b/', '/birds/'))
return None
The implementation may need a bit of work but the actual method stands, check the current path and if the /b/ is present, redirect it to your required destination.
Otherwise, you could specify a redirect view by iterating over every url in birds but this would get messy for urls in birds that are a namespace to other urls.
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.