I have a loading page in Django while some server side processes are ongoing the view is;
def loading_page( request ):
testname = request.session['testname']
done_file = filepath_to_design_dir( testname + ".done" )
if os.path.exists( done_file ):
request.session["job_stat"] = "job_done"
return redirect( "single_output/")
else:
return render( request, 'single_design/loading.html' )
My problem is that the redirect goes to;
http://127.0.0.1:8000/single_design/loading_page/single_output/
Rather than
http://127.0.0.1:8000/single_design/single_output
What is the correct way to do this???
EDIT : issue resolved, thanks guys.
Urls as requested
from django.conf.urls import url , include
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', views.get_single_input, name='single_design_input'),
url(r'^single_output/$', views.single_output, name='single_output'),
url(r'^loading_page/$', views.loading_page, name='loading_page'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
The correct way is not to use hardcoded link. Use urlresolvers.
return redirect("some_view_name")
Without the leading slash, the current value single_output/ is treated as a relative url, which is appended to the current url /single_design/loading_page/ to give /single_design/loading_page/single_output/.
You could use the relative url ../single_output, but I wouldn't recommend it. It would be better to return the url you want to redirect to, including a leading slash.
return redirect('/single_design/single_output/' )
Ideally, you should use the name of the url pattern, then Django will reverse it for you. Since you have,
url(r'^single_output/$', views.single_output, name='single_output'),
you can use the name instead of the url,
return redirect('single_output')
The advantage of using the name single_output, is that you can now change the URL in your url patterns, without having to update the view.
Related
I'm looking for a way to redirect any url that start with /D/ to the same URL with lowercased /d/.
/D/<anything_including_url_params>
to
/d/<anything_including_url_params>
I literally only want to redirect urls that start with /D/ - not /DABC/ etc...
The suffix can also be empty, eg. /D/ > /d/
Is there a way to do that in Django? It is for a third-party app with urls included in projects urls.
The alternative is to use re_path and change:
path("d/", include(...))
to
re_path(r"^[dD]/$", include(...))
but I'd rather do a redirect instead of this.
You can make a view that directs with:
# some_app/urls.py
from django.views.generic import RedirectView
# …
urlpatterns = [
path('d/', include(…)),
path(
'D/<path:path>',
RedirectView.as_view(
url='/d/%(path)s', query_string=True, permanent=True
),
),
]
Note that a redirect will however always result in a GET request, so even if the original request to D/something is a POST request for example, it will make a GET request to d/something.
Any reason why you can't use a RedirectView at all?
As per the docs:
https://docs.djangoproject.com/en/4.1/ref/class-based-views/base/#redirectview
You can register this as the literal /D/ but redirect to /d/ using the view name and passing on and args or kwargs.
I have a url like this get method in a browser it says 404 page not found error
http://localhost:8000/getup/downloadrange/ef46219d-7b33-4bdc-aab1-c3bf073dca0e/datebottom=2019-10-10&datetop=2020-10-01/
My urls.py is like this
path(
"downloadrange/<uuid:id>/(?P<datebottom>\d{4}-\d{2}-\d{2})&(?P<datetop>\d{4}-\d{2}-\d{2})/$",
views.getup,
name="getup",
),
The url pattern is not found for this. Kindly help me in this regard
my views.py
def getup(request, id, dateone, datetwo):
queryset_two = (
getup.objects.filter(process_id=id)
.filter(created_on__date__range=[dateone, datetwo])
)
return render_to_csv_response(qs)
The valid url you are expecting according to your configuration is:
http://localhost:8000/getup/downloadrange/ef46219d-7b33-4bdc-aab1-c3bf073dca0e/2019-10-10&2020-10-01/
NOT
http://localhost:8000/getup/downloadrange/ef46219d-7b33-4bdc-aab1-c3bf073dca0e/datebottom=2019-10-10&datetop=2020-10-01/
Your views have that capacity to take datebottom and datetop automatically from your url if it is valid.
Edit
As you are using path, the url confs is different. So, we will change from path to re_path to support regex:
from django.urls import re_path
re_path(
"downloadrange/(?P<id>[0-9a-f-]+)/(?P<datebottom>\d{4}-\d{2}-\d{2})&(?P<datetop>\d{4}-\d{2}-\d{2})/$",
views.getup,
name="getup",
),
I'm using Django 1.9. Is there any way to redirect a URL with a parameter in my urls.py file?
I want to permanently redirect a URL like /org/123/ to the corresponding URL /neworg/123.
I know how to redirect within a view, but I'm wondering if there's any way to do it solely inside urls.py.
You can use RedirectView. As long as the old and new url patterns have the same args and kwargs, you can use pattern_name to specify the url pattern to redirect to.
from django.views.generic.base import RedirectView
urlpatterns = [
url(r'^neworg/(?P<pk>\d+)/$', new_view, name='new_view'),
url(r'^org/(?P<pk>\d+)/$', RedirectView.as_view(pattern_name='new_view'), name='old_view')
]
I'd like to redirect url pattern with variables from urls.py.
I refer other stackoverflow solution, but I don't know when url having a variable like following code.
from django.conf.urls import patterns, url
from django.views.generic import RedirectView
urlpatterns = patterns(
url(
r'^permalink/(?P<id>\d+)/foo/$',
RedirectView.as_view(url='/permalink/(?P<id>\d+)/')
),
)
With this code, django will redirect /permalink/1/foo/ to /permalink/(?P<id>\d+)/, not the /permalink/1/.
Is there any solution without using views.py?
Of course I know solution using controller, but I wonder is there any simpler solution with using url pattern.
Passing url='/permalink/(?P<id>\d+)/' to RedirectView will not work, because the view does not substitute the named arguments in the url.
However, RedirectView lets you provide the pattern_name instead of the url to redirect to. The url is reversed using the same args and kwargs that were passed for the original view.
This will work in your case, because both url patterns have one named argument, id.
urlpatterns = [
url(r'^permalink/(?P<id>\d+)/foo/$',
RedirectView.as_view(pattern_name="target_view"),
name="original_view"),
url(r'^permalink/(?P<id>\d+)/$', views.permalink, name="target_view"),
]
If the target url pattern uses other arguments, then you can't use url or pattern_name. Instead, you can subclass RedirectView and override get_redirect_url.
from django.core.urlresolvers import reverse
from django.views.generic import RedirectView
class QuerystringRedirect(RedirectView):
"""
Used to redirect to remove GET parameters from url
e.g. /permalink/?id=10 to /permalink/10/
"""
def get_redirect_url(self):
if 'id' in self.request.GET:
return reverse('target_view', args=(self.request.GET['id'],))
else:
raise Http404()
It would be good practice to put QuerystringRedirect in your views module. You would then add the view to your url patterns with something like:
urlpatterns = [
url(r'^permalink/$', views.QuerystringRedirect.as_view(), name="original_view"),
url(r'^permalink/(?P<id>\d+)/$', views.permalink, name="target_view"),
]
As an example:
view.py
def view1( request ):
return HttpResponse( "just a test..." )
urls.py
urlpatterns = patterns('',
url( r'^view1$', 'app1.view.view1'),
)
I want to get the URL path of view1. How can I do this.
I want to avoid hard coding any URL paths, such as "xxx/view1".
You need reverse.
from django.urls import reverse
reverse('app1.view.view1')
If you want to find out URL and redirect to it, use redirect
from django.urls import redirect
redirect('app1.view.view1')
If want to go further and not to hardcode your view names either, you can name your URL patterns and use these names instead.
This depends whether you want to get it, if you want to get the url in a view(python code) you can use the reverse function(documentation):
reverse('admin:app_list', kwargs={'app_label': 'auth'})
And if want to use it in a template then you can use the url tag (documentation):
{% url 'path.to.some_view' v1 v2 %}
If you want the url of the view1 into the view1 the best is request.get_path()
As said by others, reverse function and url templatetags can (should) be used for this.
I would recommend to add a name to your url pattern
urlpatterns = patterns('',
url( r'^view1$', 'app1.view.view1', name='view1'),
)
and to reverse it thanks to this name
reverse('view1')
That would make your code easier to refactor
Yes, of course you can get the url path of view named 'view1' without hard-coding the url.
All you need to do is - just import the 'reverse' function from Django urlresolvers.
Just look at the below example code:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
def some_redirect_fun(request):
return HttpResponseRedirect(reverse('view-name'))
You can use the reverse function for this. You could specify namespaces and names for url-includes and urls respectively, to make refactoring easier.
Universal approach
install Django extensions and add it to INSTALLED_APPS
Generate a text file with all URLs with corresponding view functions
./manage.py show_urls --format pretty-json --settings=<path-to-settings> > urls.txt
like
./manage.py show_urls --format pretty-json --settings=settings2.testing > urls.txt
Look for your URL in the output file urls.txt
{
"url": "/v3/blockdocuments/<pk>/",
"module": "api.views.ganeditor.BlockDocumentViewSet",
"name": "block-documents-detail",
},