Flask reroute always using default function argument - flask

Given a route such as the one below, I have found that if I have a default value for the argument test it won't change when passing a value via url_for with a redirect. What I'd like is to change the parameter test when rendering the template, depending on whether a form was just submitted or not.
#app.route('/view_story/<story_id>', methods=['GET', 'POST'])
def view_story(story_id, test='no'):
...
if current_user.is_authenticated:
if request.method == 'POST':
#Add stuff to database from the form.
return redirect(url_for('view_story', story_id=story_id, test='yes'))
return render_template('story.html', test=test)

Try the below code:
#app.route('/view_story/<story_id>', defaults={"test": "no"})
#app.route('/view_story/<story_id>/<test>', methods=['GET', 'POST'])
def view_story(story_id, test):
...
if current_user.is_authenticated:
if request.method == 'POST':
#Add stuff to database from the form.
return redirect(url_for('view_story', story_id=story_id, test='yes'))
return render_template('story.html', test=test)

Related

Views are different but rendering same template

i want to use slug field in both url which is
path('<slug:title>/',views.news_read,name="news_read"),
path('<slug:title>/',views.movie_read,name="movie_read"),
but both the url picking same template instead of their template i am trying to create blog site
i don't understand both the url are uniques so why django is picking wrong template
my views for both the url
def movie_read(request, title):
movie = Movie.objects.filter(urltitle=title)
if request.method == 'POST':
form = Commentform(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Thank You For Your Comment')
else:
form = Commentform()
return render(request,'movie_read.html',{'movie':movie,'form':form})
def news_read(request, title):
news = News.objects.filter(urltitle=title)
if request.method == 'POST':
form = Commentform(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Thank You For Your Comment')
else:
form = Commentform()
return render(request,'news_read.html',{'news':news,'form':form})
but i when do some change like this it work
path('<slug:title>/news',views.news_read,name="news_read"),
path('<slug:title>/movie',views.movie_read,name="movie_read"),
but this doesn't look good any idea what to do solve the issue
Django will "fire" the first path that matches the URL. This thus means that for every slug you enter, news_read will fire.
You can solve this by trying to query both models, and then decide which to use, like:
def my_view(request, title):
is_movie = Movie.objects.filter(urltitle=title).exists()
if is_movie:
return movie_read(request, title)
else:
return news_read(request, title)
def movie_read(request, title):
# …
def news_read(request, title):
# …
and then thus trigger the my_view function if it is a slug:
path('<slug:title>/', views.my_view, name='news-movie-read'),
but a more elegant solution is to simply define two non-overlapping URL patterns:
path('news/<slug:title>/', views.news_read,name='news_read'),
path('movie/<slug:title>/', views.movie_read,name='movie_read'),
This also will prevent clashes where a Movie object and a News object have both the same url_title since in that case, it will always use the movie_read view.
I seems that tou url path is the same, that is why django picking wrong view.
Try to change urls to this:
path('news/slug:title/',views.news_read,name="news_read"),
path('movies/slug:title/',views.movie_read,name="movie_read"),

What does request.method == "POST" mean in Django?

I am using this thing in my views quite a lot but I want to know what exactly does that mean.
What happens when we write request.method == "GET" or request.method == "POST"?
The result of request.method == "POST" is a boolean value - True if the current request from a user was performed using the HTTP "POST" method, of False otherwise (usually that means HTTP "GET", but there are also other methods).
You can read more about difference between GET and POST in answers to the question Alasadir pointed you to. In a nutshell POST requests are usually used for form submissions - they are required if processing a form would change server-side state (for example add user to a database, in case of a registration form). GET is used for normal HTTP requests (for example when you just type an URL into your browser) and for forms that can be processed without any side-effects (for example a search form).
The code is usually used in conditional statements, to distinguish between code for processing a submitted form, and code for displaying an unbound form:
if request.method == "POST":
# HTTP Method POST. That means the form was submitted by a user
# and we can find her filled out answers using the request.POST QueryDict
else:
# Normal GET Request (most likely).
# We should probably display the form, so it can be filled
# out by the user and submitted.
And here is another example, taken straight from Django documentation, using Django Forms library:
from django.shortcuts import render
from django.http import HttpResponseRedirect
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render(request, 'contact.html', {
'form': form,
})
request.methodreturns the type of the request method it may be GET,POST,PUT,DELETE etc.
after returning you are comparing it with your string.
comparison operator always provides a boolean value(True or False).
Some times we need to handle the functionality based on the requested method type.
if request.method == "GET":
# functionality 1
elif request.method == "POST":
# functionality 2
elif request.method == "PUT":
# functionality 3
elif request.method == "DELETE":
# functionality 4
for request method GET data is passed along with url.
for request method POST data is passed inside body. In terms of security method type POST is better one.
book_id = Book.objects.get(id=id)
if request.method == 'POST':
book_save == BookForm(request.POST, request.FILES, instance=book_id)
if book_save.is_valid():
book_save.save()
else:
book_save = BookForm(instance=book_id)
y = {
'form':book_save,
}
return render(request, 'pages/update.html', y)

The view didn't return an HttpResponse object error when form is not valid: django

I've used Django forms. I have this function in views.py:
def func(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
//do processing
return HttpResponseRedirect('/')
else:
form = MyForm()
return render_to_response("checkbox.html", RequestContext(request, {'form':form}))
but when form is invalid, it shows me the error: The view didn't return an HttpResponse object. I've searched and realized every where the view functions are like this, but I don't know why mine has error. It seems it doesn't know what to do, while form in invalid!!! Why it doesn't show the page and show user the form errors? can you please help me?
When the form is invalid, the view just returns since else part of the if statement is only evaluated when the request.method == "POST" is False, which it is not...
To fix this, the following is the usual pattern for making form views:
def func(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
//do processing
return HttpResponseRedirect('/')
else:
form = MyForm()
# outside of the else clause
# if the form is invalid, then it will also show the error messages to the user
return render_to_response("checkbox.html", RequestContext(request, {'form':form}))
You already have your answer on #miki725 post. Just a suggestion you might want to consider GET as the default behaviour to avoid those if .. else:
def func(request):
# GET is the default behaviour
form = MyForm()
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
//do processing
return HttpResponseRedirect('/')
return render_to_response("checkbox.html", RequestContext(request, {'form':form}))

Django while deleting entry getting error local variable 'delete' referenced before assignment

Can someone explain and correct me on deleting entries?
url(r'^remove/(?P<id>\d+)/$', 'registration.views.removerequest'),
<a href = '/remove/{{ object.id }}/'>remove</a>
#view
def removerequest(request,id):
if not request.user.is_authenticated():
get_objects=Todos.objects.get(pk=id)
return HttpResponseRedirect('/remove/')
if request.method =='POST':
delete= get_objects.delete()
return HttpResponseRedirect('/profile/')
context = {'delete':delete}
return render_to_response('remove.html',context,context_instance=RequestContext(request))
fixed as good as i could...as Daniel said...there are tooo many logic errors.
template
<a href = '/remove/{{ object_to_delete.id }}/'>remove</a>
view
from django.contrib.auth.decorators import login_required
#login_required #only allow deletion for authenticated users
def removerequest(request,id):
get_objects=Todos.objects.get(pk=id) #get the todo object
if request.method =='POST': # if form is submitted
delete= get_objects.delete() # delete the shit
return HttpResponseRedirect('/profile/') # return to profile URL
# else
context = {'object_to_delete': get_objects} # pass the todo object to the context
return render_to_response('remove.html',context,context_instance=RequestContext(request)) #return all

passing a value to an HttpResponse request

I have a urlpattern that brings a template that allows the fields of a model instance to be viewed:
(r'^display/(?P<id>\w+)/', display_record),
I also have a view function that allows a single instance to be edited. When the object is saved, it simply returns to the same template:
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
After the save, how do I return to the display template, as opposed to refreshing the same view?
the code would look something like the following but I need a way to pass the object "id" to the HttpResponse request:
def edit_record(request, id):
if request.method == 'POST':
a=ProjectRecord.objects.get(pk=id)
form = RecordForm(request.POST, instance=a)
if form.is_valid():
form.save()
return HttpResponseRedirect**('/display/(?P<id>\w+)/')**
else:
a=ProjectRecord.objects.get(pk=id)
form = RecordForm(instance=a)
return render_to_response('productionModulewire.html', {'form': form})
You're overcomplicating things. You already know what the ID is, so why can't you just put it back into the URL?
return HttpResponseRedirect('/display/%s/' % id)
or, better, since it doesn't tie you to a particular hard-coded URL:
return HttpResponseRedirect(reverse('edit_record', kwargs={'id':id}))