On one of my pages I want to display a button, whenever this button is clicked I want to display the following in my display "Button clicked".
However the following message displays in my console.""GET /account/all-plan/?print_btn=Click HTTP/1.1" 200 5025"
This is my view
def print_from_button(request):
if(request.GET.get('print_btn')):
print('Button clicked')
return HttpResponse('testklik')
html
<form method="get">
<input type="submit" class="btn" value="Click" name="print_btn">
</form>
and url in urls.py
path('all-plan/print_from_button', views.print_from_button, name='print_from_button'),
Can anyone point me into the right direction, I cannot find what I am missing. Thanks a lot!
You seem to have to URLs:
/account/all-plan/
/account/all-plan/print_from_button
In the first URL you are creating a <form> which uses the GET method, but no action attribute is specified. The result is that your form submits to the same URL as the current page (first URL). This can be seen as your console print says it's using the first URL with an extra GET parameter.
In order to get your form to use the correct URL you need to specify the action attribute with the correct URL:
<form method="get" action="{% url "app_name:print_from_button" %}">
...
</form>
Related
I am trying to create a simple search form(search by zip code), but am struggling to pass the user's input to a view:
<form action="{% url 'search_results' query %}" method="post">
<div>
{% csrf_token %}
<input type = 'text' name = 'query' placeholder="Zip Code" />
<button type="submit" name="button">Find Jobs</button>
</div>
</form>
urls.py:
path('search_results/<str:query>', job_views.search_results, name = 'search_results'),
views.py:
def search_results(request, query):
query = request.GET['query']
return HttpResponse(query) # just trying to see if this view has access to 'query'
I'm not sure what is going on here. This returns
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'search_results' with a
rguments '('',)' not found. 1 pattern(s) tried: ['search_results\\/(?P<que
ry>[^/]+)$']
Thanks for any help!
In your form, at the line: action="{% url 'search_results' query %}", you are trying to pass query to the url tag, which would be fine if query had a value, but in your case query isn't defined.
Instead, you're form should look like this:
<form action="{% url 'search_results' %}" method="GET">
<div>
<input type = "text" name = "zip_code" placeholder="Zip Code" />
<button type="submit" name="button">Find Jobs</button>
</div>
</form>
Notice that I removed query from your url tag, and changed the method to GET, see this question for details.
Now change your path:
path('search_results', job_views.search_results, name = 'search_results')
You don't need to add query to the path, because Django will do it for you in your view:
def search_results(request):
zip_code = request.GET.get('zip_code')
print(zip_code)
...
That's not how templates work.
Templates are used to produce a response, which gets returned to the requester. In this case, your main view produces an HTML document which will be passed to a browser. That document contains results of the url template tag, which is determined before the user even sees it. Template tags are not a way to refer to the state of DOM objects!
Instead, you should usually have a view with a stable URL, not varying with the query. Typically you'll then extract the query text from the form data representation - here, it'd be the request.POST dictionary-like object or (usually better) a Django form that you bind to the POST data, because your form uses method="post".
It would be possible to use Javascript to edit the DOM and change your form action prior to submitting it to include the query text, but that's not the usual pattern for working with forms. And template tags will never do that - they're only used to generate the response.
I am new to scrapy and in general web tech.
While working on a scrapy example to perform auto login. I came across 1 field , referrer url . I am wondering when do i need to this.
return scrapy.FormRequest.from_response(
response,
url='www.myreferrer.com', #when do i need this ???
formnumber=1,
formdata=self.data['formdata'],
callback=self.after_login
)
I tested with and without it and it works in both instances.
I understand that referrer url is for security but how do i determine from html code that i need or dont need this ?
ADDON
The following html form required the url to be defined :
<form id="login" enctype="multipart/form-data" method="post" action="https:///myshop.com/login/index.php?route=account/login">
I am a returning customer.<br>
<br>
<b>E-Mail Address:</b><br>
<input type="text" name="email">
<br>
<br>
<b>Password:</b><br>
<input type="password" name="password">
<br>
Forgotten Password<br>
<div style="text-align: right;"><a class="button" onclick="$('#login').submit();"><span>Login</span></a></div>
</form>`
class FormRequest(Request):
# delete some code here
#classmethod
def from_response(cls, response, formname=None, formid=None, formnumber=0, formdata=None,
clickdata=None, dont_click=False, formxpath=None, formcss=None, **kwargs):
url = _get_form_url(form, kwargs.pop('url', None))
def _get_form_url(form, url):
if url is None:
return urljoin(form.base_url, form.action)
return urljoin(form.base_url, url)
if the url is empty, it uses form tag's action attribute to get the URL.
if the url is not empty, then it use the URL you give to it.
the base_url comes from the response.
def _get_form(response, formname, formid, formnumber, formxpath):
"""Find the form element """
root = create_root_node(response.text, lxml.html.HTMLParser,
base_url=get_base_url(response))
so, when the action attribute does not exist or the login requests is not sent to the action URL, you need to pass the argument.
I am trying to make a button redirect the user to a new url after they submit a form. This is how it is right now, and it works properly and all the data gets sent to the django database.
<form method='POST' action='' class="col-md-6 col-md-offset-7" style="background-color: lightgreen; border-radius: 10px">
However, when I change the action to
action="{% url 'ridesharing:request-success' %}",
the redirect works, but the data does not go to my django database.
What is going on here?
You seem to have some confusion here. The action of the form is where the browser will send the data. Obviously, if you don't point that at the view which actually processes the data, then it won't be saved.
To redirect after a post, your view should return a redirect.
When you declare a form with an empty action attribute:
<form method='POST' action=''>
the POST data will be sent to the same URL. This is useful because if there is some error in the form, it's easy to re-display it with all fields filled with values entered by the user. Then, when the form becomes valid, a redirect is done to the confirmation page.
When you declare your form that way:
<form method='POST' action='{% url 'ridesharing:request-success' %}'>
The data entered by the user in the form will be sent to the view request-success. But this view probably only render the template of the confirmation page. If you want to correctly handle data from the form, you have to set action attribute of your <form> to the same view, or easier, keep it empty.
I do not understand why Daniel Roseman's post isnt accepted as the answer. It helped me when I wanted to redirect a create form to its update form.
Basically in the view of the app I defined the get_success_url to reverse_lazy to the data-update.
def get_success_url(self):
return reverse_lazy('app_name:data-update')
Just replace the 'app_name:data-update' with the appropriate url.
I am new to Django and I have a simple question. Here is a view :
def watchmovie(request, idmovie):
[...]
return render(request, 'movies/watch_movie.html', locals())`
and I would like to create a simple form :
an IntegerField that would redirect to the correct url :
if I submit "42" it will redirect me to the view watchmovie with the parameter 42 as idmovie.
How can I do that?
I tried something like that
<form action="{% url "movies.views.watchmovie" %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
my url.py is
from django.conf.urls import patterns, url
urlpatterns = patterns(
'movies.views',
url(r'^movie/(?P<idmovie>\d+)$', 'watchmovie'),
)
and Django says
Reverse for 'movies.views.watchmovie' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['movies/movie/(?P<idmovie>\\d+)$']
Thank you!
The reason you are getting that error is because of a mistake in your url tag usage. Your watchmovie view url definition expects an argument to be supplied for idmovie. Since you are not supplying any argument in your url tag call, it looks only for urls which do not require an argument. Since there is none, you get an error.
But that is just a symptom. The real issue is that the way you have this structured there is no view listening for a post from your form.
The easier way to structure this is to use the same view to both display the form and to play the movie. If your view is hit with a GET request, display the form. If it is hit with a POST, validate the form (which will contain the movie id) and then respond with the page that plays the movie. That way there is no need to pass idmovie within your url.. you can remove that from your url definition and also remove the need to specify the action= attribute in your tag.. it will just post right back to where it came from.
I'm new to django and for practice I'm trying to program my own version of the all familiar 'todo list' app.
I have some page that displays all todo list items the user has entered, along with a button to edit each one. The edit button sends the user to another page with a form to enter in the changes to the item.
It's possible for the user to change everything about the item. Obviously request.POST gives me all the information the user just put into the form, but I want this information to rewrite the info of the item they originally clicked on. So how do I write the view code to find out what that original item was?
I guess I could format my form submit button to:
<button type="submit" name="save" value={{ item.pk }}>Save</button>
and get the primary key that way
but lets say I had passed two items to the edit page and I wanted to give the user the ability to combined them. Again, I could figure out what those items were by doing:
<button type="submit" name="save" value='{{ item1.pk }} {{ item2.pk }}'>Save</button>
then
request['save'].split(' ')
this seems kinda stupid though. Is there some other, less brute force, way?
like a:
request.tell_me_all_items_passed_to_the_template
kind of thing?
In case someone else has the same question
So instead of doing this:
template
<form method="post" action="/list/saving/">
<!--- form fields --->
<button type="submit" name="save" value='{{ item.pk }}'>Save</button>
</form>
url.py
(r'^list/saving/$', save)
views.py
def save(request):
....
item = Item.objects.get(pk=request.POST['save'])
....
do this:
template
<form method="post" action="{% url todolist.views.save item.pk %}">
<!--- form fields --->
<button type="submit" name="save">Save</button>
</form>
url.py
(r'^list/saving/(\d+)/$', save)
views.py
def save(request, pk):
....
item = Item.objects.get(pk=pk)
....
More info on url reversing
If you really need to, just use hidden inputs. But, this is unnecessary anyways. The user may be able to change "everything" about the item, but they can't change the pk (or at least they shouldn't be able to... don't give them the option to). The pk is what Django uses to identify an object, so this is already handled for you. Not sure what the issue here is.