How to call a specific url from Django views? - python

I want to make a call to specific url pattern from Django Views.
The call should be inside first IF conditional and outside the inner if. Is the any function which provides redirection? Or something like redirect(map_vertical_crawl)? The code portion for
Django Views:
def add_vertical(request):
if request.method == 'POST':
form = VerticalForm(request.POST)
if form.is_valid():
form.save()
#I WANT TO CALL URL EXACTLY AT THIS POINT, INSIDE OUTER IF.
verticals = Verticals.objects.all()
return render(request, 'cfman/add_vertical.html',
{'form': VerticalForm(),
'verticals': verticals}
)
Django URLS:
from django.conf.urls import url
from . import views, apps
urlpatterns = [
#Generates Login Screen
url(r'^$', views.LoginView.as_view(), name="login"),
#Directs to manager view level 1
url(r'^manager/$', views.verticals_view, name="manager"),
#Directs to manager view level 2
url(r'^manager/(?P<verticalid>\d+)/$', views.source_list, name='source_list'),
#Add Vertical
url(r'^verticals/add_vertical/$', views.add_vertical, name="add_vertical"),
#Add Source
url(r'^sources/add_source/$', views.add_source, name="add_source"),
#Add Crawl Type
url(r'^crawls/add_crawl/$', views.add_crawl, name="add_crawl"),
#Map verticals and crawl types
url(r'^vertical_crawl/$', views.map_vertical_crawl, name="map_vertical_crawl"),
]
I want to call the last url pattern , 'map_vertical_crawl' from views.

Django's built-in redirect() accepts a view name as parameter, so just do:
redirect('cfman:map_vertical_crawl')

Related

Use URL data to fill form in Django with Class Based Views

I have 2 Models: Projects and Members, each one with a form. I was able to add to the URL the number of the project (id) this:
class PageCreate(CreateView):
model = Page
form_class = PageForm
success_url = reverse_lazy('members:create')
def get_success_url(self):
return reverse_lazy('members:create', args=[self.object.id])
When I finish of filling the Project form, it redirects the page to the Member form.
What I want to do is to extract the ID of the Project from the URL and use it in the Member form. I cannot think any other solution.
Currently I have a Selection list to select the Project in the Member form but I want the Project loaded as soon as is created.
I am using the CreateView in the models for both Projects and Members. This is the view for MemberCreate
#method_decorator(login_required, name='dispatch')
class MemberCreate(CreateView):
model = Member
form_class = MemberForm
success_url = reverse_lazy('pages:pages')
Only attempt I had to visualize the ID in the HTML was using
{{ request.get }}
To somehow get the value from the GET but I could not do it.
Url Parameters
import imp
from django.urls import path
from .views import PageListView, PageDetailView, PageCreate, PageUpdate, PageDelete, MemberCreate, MemberDelete, MemberUpdate
pages_patterns = ([
path('', PageListView.as_view(), name='pages'),
path('<int:pk>/<slug:slug>/', PageDetailView.as_view(), name='page'),
path('create/', PageCreate.as_view(), name='create'),
path('update/<int:pk>', PageUpdate.as_view(), name='update'),
path('delete/<int:pk>', PageDelete.as_view(), name='delete'),
], 'pages')
members_patterns = ([
path('create/<int:pk>', MemberCreate.as_view(), name='create'),
path('update/<int:pk>', MemberUpdate.as_view(), name='update'),
path('delete/<int:pk>', MemberDelete.as_view(), name='delete'),
], 'members')
Stuff parsed from the URL ends up in the view's self.kwargs. From
return reverse_lazy('members:create', args=[self.object.id])
you pass through an URL like
path( 'create/<int:project>', MemberCreateView.as_view(), name='create' )
and in the view, the id is now self.kwargs['project']. (note, an URL can specify multiple named variables separated by slashes, it's not limited to just one). You typically then use
project = Project.objects.get( pk = self.kwargs['project'] )
Request.GET is something different: it's where the dict encoded as a querystring goes. If your client supplies
http://server/app/foo?bar=27&baz=hello
then when you arrive in the view which handles app/foo, request.GET contains
{ 'bar':'27', 'baz':'hello' }
(actually it's a QueryDict, not a Python dict, which has some subtle diffreernces. Consult the Django documentation. The main difference is that the values attached to keys can be multi-valued, for a querystring like ?bar=27&bar=54&bar=silly

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

django-contact-form how to use the form inside any template, without a new url?

I have installed django-contact-form, and the default url to the form is 'contact/'. But, I already have my own contact page, let's call it 'contact_us/', I wish to include the form inside 'contact_us/', using the url and view I already have for 'contact_us/'.
The usual way to do that is by using {% extends 'contact_us' %}, but if I do this, and remove my original 'contact_us/' url, it gives me an ReverseError.
The way I think that would be possible is if sent the ContactFormView (from django-contact-form) as context to 'contact_us/', but I think that's not possible because each view has it's own url.
I want to know a way to be able to put the form easily inside of any template. There's probably a simple way to do that and I don't know.
You can call the ContactFormView from the contact_us by:
1. By overriding the url
urls.py
from contact_form.views import ContactFormView
from django.views.generic import TemplateView
urlpatterns = [
# ... other URL patterns for your site ...
url(r'^contact_us/$',
ContactFormView.as_view(),
name='contact_form'),
url(r'^contact_us/sent/$',
TemplateView.as_view(template_name='contact_form/contact_form_sent.html'),
name='contact_form_sent'),
]
2. If you want to customize this view
In views.py
from contact_form.views import ContactFormView
class CustomContactFormView(ContactFormView):
# Customize any function that you want to
template_name = 'custom_template.html'
urls.py
from views import CustomContactFormView
urlpatterns = [
# ... other URL patterns for your site ...
url(r'^contact_us/$',
CustomContactFormView.as_view(),
name='contact_form'),
]

passing data between class based forms

I am fairly new to Django and class based forms, and I am having trouble understanding how these interact with each other. Following from the django project example, I have tried to build a "search form", which would sit on all pages of my project:
# forms.py
from django import forms
class SearchForm(forms.Form):
myquery = forms.CharField(max_length=255,label="", help_text="sq")
def __unicode__(self):
return self.myquery
# views.py
from searchapp.forms import SearchForm
from django.views.generic.edit import FormView
from django.views.generic import TemplateView
class SearchView(FormView):
template_name = 'index.html'
form_class = SearchForm
success_url = '/searchres/'
def form_valid(self, form):
thequery=form.cleaned_data.get('myquery')
return super(SearchView, self).form_valid(form)
class Meta:
abstract = True
class SearchResView(SearchView):
template_name = 'searchres.html'
#urls.py
from django.conf.urls import patterns, include, url
from django.conf import settings
from deals.views import IndexView
from searchapp.views import SearchView, SearchResView
urlpatterns = patterns('',
url(r'^index/', SearchView.as_view(),name="home"),
url(r'^searchres/', SearchResView.as_view(),name="searchresx"),
)
The plan is the start off with a simple form for user to enter the search query, and also show the input form on the results page. I have the following questions here (sorry - I am a Django newbie esp. to Class Based Views):
How does one pass data ("thequery") to the success_url? i.e I would like success_url to have access to "thequery" so that I can use something like {{thequery}} on my template tags.
Upon submitting the form(name="home"), I see POST data from the form on my firebug, but I am able to see just "myquery" rather than "thequery". How does one use get_context_data() here to add/post "thequery" variable aswell?
Finally, I was wondering if it would be possible to construct the success_url based on "thequery" string i.e something like success_url = '/searchres/?q=' + thequery
Thank you in advance - I am hoping to learn more.
I would suggest using function based views for this. If you choose to subclass a generic view you will need to dig through a lot of documentation and possibly source code, to find the right methods to override. (If you're really keen then look at the ListView class along with the get_queryset(), get() and post() methods)
A single django view will normally handle both rendering the empty form AND processing the submitted form.
So the search page (both the form and the results), live at http://your-site.com/search. Your url conf is -
urlpatterns = patterns('',
#...
(r'^search/$', 'searchapp.views.search'),
)
And your view looks something like this -
def search(request):
if request.method == 'POST':
form = SearchForm(request.POST)
if form.is_valid():
my_query = form.cleaned_data['myquery']
object_list = YourModel.objects.filter(# some operation involving my_query)
return render_to_response('search_results.html', {'object_list': object_list})
else:
form = SearchForm()
render_to_response('search_form.html', {'form': form})
(Note I've assumed your form method is post rather than get - I know this isn't great http but it's a common pattern with django)
To respond to your questions -
Don't use your own method for cleaning data. Add a clean_myquery method to your form and access it with form.fields['myquery'].clean() (or if you've called is_valid() on your form, it's accessible with just form.cleaned_data['myquery']).
You want to try and avoid passing data for processing to the template. Do as much processing as you can in the view, then render the template. However if you want to pass myquery as a string for the template to render, then add it in to the context dictionary (the second non-key-word argument) in render_to_response -
return render_to_response('search.html', {'object_list': object_list, 'myquery': my query})
The post data is constructed from the form fields. You don't have a form field thequery. The view is processing the POST data - it's not creating it that's done by the html (which in turn is constructed by the Form class). Your variable thequery is declared in the view.
Django's URL dispatcher ignores query strings in the URL so http://your_site.com/ssearch will be processed by the same view as http://your_site.com/search?myquery=findstuff. Simply change the html in the template from <form method='post'> to and access the data in django with request.GET. (You'll need to change the code from the view I described above to include a new check to see whether you're dealing with a form submission or just rendering a blank form)
Have a good read of the docs on views, forms and the url dispatcher.

Categories