How to send url as slug field into url in Django - python

I have my urls.py as this:
from django.urls import path
from . import views
urlpatterns = [
path('link',views.get_text,name='text'),
path('link/<link>',views.show,name='show')
]
When I enter a url like http://127.0.0.1:8000/link/https://www.geeksforgeeks.org/gate-cs-notes-gq/, it is showing page not found as it is checking the / in the slug url. I am storing the url and other fields in database, so I want to retrieve the database objects using the url. How to do such that when I enter a url in the browser, it takes the entire url as link field in urls.py , so that I can retrieve the db objects from views.py in this way:
def show(request,link):
objs = Links.objects.filter(link=link).values()
return HttpResponse('link')

Pass the URL in the querystring of the requesting URL: http://127.0.0.1:8000/link/?link=https://www.geeksforgeeks.org/gate-cs-notes-gq/
The data from the querystring is available in the request.GET dictionary in your view
def link_view(request):
if 'link' in request.GET:
objs = Links.objects.filter(link=request.GET['link']).values()
return HttpResponse(...)
else:
# Handle no link provided (views.get_text)
Your url patterns then only need to define one path that handles both cases where a URL is provided or not
urlpatterns = [
path('link/', views.link_view, name='link_view'),
]

To redirect, you can use HttpResponseRedirect. It will redirect the url without specifying the view. It you write HttpResponseRedirect('/link'), it will redirect you to http://127.0.0.1:8000/link. Since you mentioned, redirect from another view, you do in this way:
def link_view(request):
if 'link' in request.GET:
objs = Links.objects.filter(link=request.GET['link']).values()
return HttpResponse(...)
else:
# do something when no link provided (views.get_text)
return HttpResponseRedirect('/link?'+str(link))#str(link) is the url you want to get

Related

Build Django URL for export_selected_objects. Example function out of the official django documentation

I am trying to build an URL that matches the redirect out of this function:
def export_selected_objects(modeladmin, request, queryset):
selected = queryset.values_list('pk', flat=True)
ct = ContentType.objects.get_for_model(queryset.model)
return HttpResponseRedirect('/export/?ct=%s&ids=%s' % (
ct.pk,
','.join(str(pk) for pk in selected),
))
That is what I have tried:
from django.urls import path, re_path
from . import views
urlpatterns = [
re_path(r'^export/(?P<ct>[0-9]{2})/(?P<ids>[0-9]{4})/$', views.test),
path('export/<int:ct><int:ids>/', views.test),
path('export/<int:ct>/<int:ids>/', views.test),
path('export/<ct><ids>/', views.test),
]
But none of these match.
Error Message
Could someone give me a hint about what I'm missing here?
You are generating a URL with query parameters, that looks like this:
/export/?ct=%s&ids=%s
The part from ? onwards is ignored by the URL resolver. Your URL file is expecting a format like this:
/export/<ct>/<ids>/
But the URL you are requesting does not match that and equally nothing in the file matching your URL.
You can either:
a) add path('export/', ...) to your urls.py file
b) change the generated URL string to /export/%s/%s/

Django Redirect by Name - No Reverse Match Error

My django project name is 'exercises' and the app name is 'practice'. This basic application allows a user can navigate to different pages with a button click. The reference to each page uses the following href:
{% url 'practice:redirector' project.pk %}
Where practice:redirector points to my app (practice) url path named redirector. It is parameterized with the primary key of the page which I am trying to redirect to. See below
from django.urls import path
from practice import views
app_name = "practice"
urlpatterns = [
path('', views.all_sites, name="all_sites"),
path('<int:pk>', views.redirector, name='redirector'),
path('clickToAddItems', views.clickToAddItems, name='clickToAddItems'),
path('displayEvens', views.displayEvens, name='displayEvens'),
path('displayMousePosition', views.displayMousePosition, name='displayMousePosition'),
path('luckySevens', views.luckySevens, name='luckySevens'),
]
This url points to the views within practice. There, I have a view set up for each page that corresponds to the name that the page will display. I also have a re director view that uses the pk passed in the url to pull the relevant page from my database and use the name as the argument in the redirect() shortcut:
from django.shortcuts import render, redirect
from practice.models import Project
app_name = "practice"
# Create your views here.
# Main list of javascript sites
def all_sites(request):
# query my project model to return all site objects
projects = Project.objects.all()
# return a rendered template with the site information passed into it
return render(request, 'practice/all_sites.html', {'projects':projects})
def clickToAddItems(request):
return render(request, 'practice/clickToAddItems')
def displayEvens(request):
return render(request, 'practice/displayEvens')
def displayMousePosition(request):
return render(request, 'practice/displayMousePosition')
def luckySevens(request):
return render(request, 'practice/luckySevens')
def redirector(request, pk):
project = Project.objects.get(pk=pk)
site_name=project.title
return redirect(site_name, permanent=True)
I am expecting django to use the redirector view to redirect depending on the provided name. Using the debugger, I can see that the database is correctly queried and the correct name is passed to the redirect with each url:
C:\Users\User\my_repository\my_repository\Dev\small-projects\practice\views.py, line 29, in redirector
def luckySevens(request):
return render(request, 'practice/luckySevens')
def redirector(request, pk):
project = Project.objects.get(pk=pk)
site_name=project.title
return redirect(site_name, permanent=True)
# Local vars:
#(These are the local variables tracked by the debugger, not project code)
pk = 1
project = <Project: Project object (1)>
request = <WSGIRequest: GET '/practice/1'>
site_name = 'clickToAddItems'
However, I get a NoReverseMatch error because django is using the project url file instead of my application url file to find the corresponding view.
C:\Users\User\my_repository\my_repository\Dev\small-projects\venv\lib\site-packages\django\urls\base.py, line 88, in reverse
else:
raise NoReverseMatch("%s is not a registered namespace" % key)
if ns_pattern:
resolver = get_ns_resolver(
ns_pattern, resolver, tuple(ns_converters.items())
)
return resolver._reverse_with_prefix(view, prefix, *args, **kwargs) …
reverse_lazy = lazy(reverse, str)
def clear_url_caches():
# Local vars:
#(These are the local variables tracked by the debugger, not project code)
args = []
current_app = None
current_path = None
kwargs = {}
ns_converters = {}
ns_pattern = ''
path = []
prefix = '/'
resolved_path = []
resolver = <URLResolver 'exercises.urls' (None:None) '^/'>
urlconf = 'exercises.url'
view = 'clickToAddItems'
viewname = 'clickToAddItems'
I need the resolver to look at 'practice.urls' instead of 'exercises.urls'. How can I do this? I have tried parameterizing urlconf=practice.urls within the redirect shortcut of the redirector view, but that does not work. Any and all feed back is very much appreciated! Thank you :)
if you want to redirect to
site_name = 'clickToAddItems'
as in your debug example, you should name the app:
site_name = 'practice:clickToAddItems'

Server not found when redirect tinyurl to original url, only slug isshown in the address bar

I am trying to create short urls for products. The short urls are generated and rendered successfully to the templates.
After I got my short URL, i copied it and search it in the browser, It says Server Not Found.
I want to redirect those short urls to original urls
For ex: My original url is - 127.0.0.1:8000/affiliation/link/10002/,
and its own short url is - tinyurl.com/yze3sjse; when i copy short url and search it on the browser, only the slug part is shown in the browser, i.e. affiliation/link/10002/ and Hence , it cannot redirect to original url
This is my functions :
Views.py
#Display individual product and render short links for all using pyshorteners
def link_view(request, uid):
results = AffProduct.objects.get(uid=uid)
slink = request.get_full_path()
shortener = pyshorteners.Shortener()
short_link = shortener.tinyurl.short(slink)
return render(request, 'link.html', {"results": results, "short_link": short_link})
Urls.py
urlpatterns = [
path('link/', views.link, name='link'),
path('link/<int:uid>/', views.link_view, name='link_view')
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Also the address bar in the browser shows: 'affiliation/link/10004/', the localhost has been missed out
Your last sentence say everything.
You are trying to access to affiliation/link/10004/ which doesn't exist.
You forget to put the DNS/IP (in your case: localhost), like: http://mywebsite.com/affiliation/link/10004/
For me, the issue come from request.get_full_path() which only return the URL content, not the full address.
Below Function converts the URL to desired short links as you need:
#Display individual product and render short links for all using pyshorteners
def link_view(request, user_id, uid):
user_id = user_id
results = AffProduct.objects.get(uid=uid)
slink = "http://127.0.0.1:8000/" + request.get_full_path()
shortener = pyshorteners.Shortener()
short_link = shortener.tinyurl.short(slink)
return render(request, 'link.html', {"results": results, "short_link": short_link, "user_id": user_id})

return to function from another function

i have a table which include all users and two columns at the end (Edit,Delete) and i just enabled the delete column, the issue is when i click on the delete icon the record will be deleted but the url will stuck on the delete function even if i used return render(request,'getUsersInfo.html') which is get all records function
Model Name: Users
urls:
from django.urls import path
from django.conf.urls import url
from . import views
urlpatterns = [
path('signup.html',views.signup,name=''),
path('getUsersInfo.html',views.getAllUsers,name=''),
url(r'^deleteUser/(?P<fullname>\D+)/$',views.deleteUser, name='deleteUser'),
# this is how to call a function without parameters url(r'^deleteUser/$',views.deleteUser, name='deleteUser'),
in the same view i have 3 functions (singup "add user", getAllUsers "get all the records to the table,deleteUser)
views:
def getAllUsers(request):
print("getAllUsers")
thesearchValue = ''
if 'SearchValue' in request.GET:
thesearchValue = request.GET['SearchValue']
print(request.GET['SearchValue'])
allUsers = User.objects.filter(fullname__icontains=thesearchValue)#all()
# return render(request,'getUsersInfo.html',{'allUsers':allUsers})
return render(request,'getUsersInfo.html',{'allUsers':allUsers})
else:
print("Empty")
allUsers = User.objects.all()
return render(request,'getUsersInfo.html',{'allUsers':allUsers})
def deleteUser(request,fullname):
print('delete the user')
todelete = User.objects.filter(fullname=fullname)
todelete.delete()
return render(request,'getUsersInfo.html')
Notice that i used return render(request,'getUsersInfo.html') which should call getAllUsers(request): but the url stuck on http://127.0.0.1:8000/deleteUser/John/
Rendering the same template as another view does not mean that you will somehow call other views. A template is nothing more than a tool to specify how to convert context data to a string, that is passed as HTTP response. You can use the same template in multiple views, and a view can render multiple templates.
You can make use of redirect(..) [Django-doc] to return a HTTP redirect response (302):
from django.shortcuts import redirect
def deleteUser(request,fullname):
print('delete the user')
todelete = User.objects.filter(fullname=fullname)
todelete.delete()
return redirect(getAllUsers)
Note: A GET request is not supposed to have side-effects, hence removing
objects when a user makes a GET request, is not compliant with the HTTP
standard. Therefore it might be better to remove a User with a POST request.

How to pass url value in django to views

My url.py is as below,
from myapp import views
urlpatterns = [
url(r'^myapp/get_requests/$', views.get_requests),
]
Now my views.py is as below,
#api_view(['GET'])
def get_request(request):
#How can I get request ID (base url here)?
return HttpResponse('test')
In the above if I do request in my browser with url as below it reaches my get_request method,
http://localhost:8080/myapp/get_requests/
But the same gives error 404 when I try with some ID in the end as below,
http://localhost:8080/myapp/get_requests/40
Now How can I get this ID number 40 in my views.py method?
Change your urls.py to
from myapp import views
urlpatterns = [
url(r'^myapp/get_requests/(?P<id>[0-9]+)$', views.get_requests),
]
Now get the id parameter in your views like this
#api_view(['GET'])
def get_request(request,id):
print id
return HttpResponse('test')
For more information check out django docs
If you want to pick up id from url, you just have to write something like this :
#login_required
def MyFunction(request, id) :
myobject = get_object_or_404(MyModel, pk=id)
context = {
"myobject" : myobject,
}
return render(request, 'my template.html', context)
And your url, you have to add url(r'^myapp/get_requests/(?P<id>\d+)/$', views.get_requests),
I assume your url is correct and he's already created with id inside. So I just gave you How I pick up object according to this ID.
There is a typo in the view function name in your above code. So, it would be get_requests not get_request.
Now coming to your question, it throws you 404 - Not Found because there is no actual route that you've defined that should expect the id after the url.
To start accepting id, add another route for it in your urls.py which has a digit regext like:
from myapp import views
urlpatterns = [
url(r'^myapp/get_requests/$', views.get_requests),
url(r'^myapp/get_requests/(?P<id>\d+)$', views.get_requests_with_id),
]
and in your views.py, define the view function to accept id parameter something like this:
#api_view(['GET'])
def get_requests_with_id(request, id):
# Now use id for whatever you want
return HttpResponse('test')
You can read about it form the official documentation here: https://docs.djangoproject.com/en/1.11/topics/http/urls/#named-groups

Categories