Im building a site using Django. I am trying to pass an input from index.html and display it in about.html using view.py.
My input seems to get passed as it is in the url at the top the browser.I am trying to store this value in a variable and display the variable in a html paragraph. However it does not show. Instead of seeing the input associated with the variable i just see the string of text with the variable name.
My index.html:
<form action="{% url 'theaboutpage' %}">
<input type="text" name="user_input">
<input type="submit" value="click here now">
</form>
My about.html:
<a href={% url 'thehomepage' %}>go back to the home page</a>
<p>{{'input_from_home_page'}}</p>
My views.py:
def about(request):
Hellothere = request.GET['user_input']
return render(request, 'about.html', {'input_from_home_page':Hellothere})
Just remove the quotation marks around the variable in your template at about.html. It should look like this:
<p>{{ input_from_home_page }}</p>
As side notes:
If the information entered in <input type="text" name="user_input"> is sensitive information, then you should consider passing it using "POST" HTTP method instead of "GET". In which case, remember to include the {% csrf_token %}. To get the passed info, you can use: request.POST.get('user_input') in your view.
By convention, you should name variables with lowercase. In your case, it's nice to have hello_there instead of Hellothere.
Related
I would like to prefill a form with URL parameters, but I am unsure as to how I should configure my URLs. I need to fill multiple fields, so is using URL parameters still the best method? In the tutorials I have been reviewing, most cases only use 1 or 2 parameters from the GET request. In my view, I am only handling one field currently as I am having trouble with just one parameter. You can see in the form model the other fields I would like to fill. Any help is greatly appreciated!
views.py
def new_opportunity_confirm(request):
form_class = OpportunityForm
account_manager = request.GET.get('account_manager')
form = form_class(initial={'account_manager': account_manager})
return render(request, 'website/new_opportunity_confirm.html', {'form': form})
urls.py
re_path(r'new_opportunity/new_opportunity_confirm/(?P<account_manager>\w+)/$', view=views.new_opportunity_confirm,
name='new_opportunity_confirm'),
new_opportunity_confirm.html
<form action="" method="post" name="newOpportunityForm" id="newOpportunityForm">
{% csrf_token %}
<div class="field">
<label class="label">Account Manager:</label>
<div class="select">
<select name="account_manager" id="account_manager" required>
<option value="{{ form }}">{{ form }}</option>
</select>
</div>
</div>
It depend if you want your parameters to be part of the url or not, and in your case I would suggest not, but let's see both method.
For GET parameters (url?var1=poney&var2=unicorn):
You do not need to configure your url. Django will do the work for you, you just have to configure what is before the interrogation point.
You can then access those with request.GET.get("var1"), or request.GET.get("var1", "default") if you want a default value in case it's not found.
In your template, you can access it with {{ request.GET.var1 }}.
For parameters in the url (url/poney/unicorn):
You need to configure the url to capture the part you want, and you need to have a parameter in the receiving view to get the one in the URL:
def new_opportunity_confirm(request, account_manager):
You can then access it like any other variable, and send it to your template if you want to have access to it there.
Again, that second way does not seem fitting to what you want to achieve.
You were halfway there, you just mixed a little bit of both methods.
I have a html page which uses jinja to display a list.
I want to be able to get the user to click a button and the list will be added to a database. I have put the button in side a form and got it to link to my url which then calls a function.
HTML:
<form method='post' action='../../accounts/myaccount/' name= '{{item}}'>
{% csrf_token %}
<a name = '{{ item }}'><button type='submit' class='btn'><img src={% static 'results/images/basket_02.png' %} alt='Image cannot be displayed right now'></button></a>
</form>
Views:
def myaccount(request):
if request.user.is_authenticated():
if request.method == 'POST':
product = request.GET.get('name')
print('product: ' , product)
return render(request, 'signup/myaccount.html')
The function is called and it prints: product: NONE , whereas i want product to be set to the list.
I know how to add to database within my views but is there a way to actually access my list?
You need to use an input tag.
<input name="name" value="{{ item }}">
With this HTML:
...
{% for thing in things %}
<form method="post">
{% csrf_token %}
{{ thing.name }}
{{ form.value }}
<input type="submit" value="Submit" />
</form>
{% endfor %}
...
My website lists multiple 'things' from my database, so there can be many forms generated on the one page. How can I somehow determine in my views.py, which 'thing's' form is being submitted?
More elaboration:
Imagine you have a page of objects listed one after the other, and each object has a like button associated with it, that adds a like to the object it is next to. That's essentially what I'm trying to do here.
The problem is, I have a form that can process the like, but how do I take that like and add it to the object that it's displayed next to on the page? (by the aforementioned 'for loop')
I'm completely confused on how to go about this, am I looking at the problem the wrong way, or is there a standard idiom around this problem that I don't know about?
Thank you :)
The most common design pattern for model instance updates is to provide the primary key of an object in the url where you are submitting your post data.
# urls.py
from django.conf.urls import *
from library.views import UpdateThing
urlpatterns = patterns('',
url('^update_thing/(?P<pk>[\w-]+)$', UpdateThing.as_view(), name='update_thing'),
# views.py
def my_view(request, pk=None):
if pk:
object = thing.objects.get(pk=pk)
form = MyModelForm(data=request.POST or None, instance=object)
if form.is_valid():
...
Now, let's specify (using Django's url template tag) that we want to submit post data for each object to the correct url.
{% for thing in things %}
<form method="post" action="{% url 'update_thing' thing.pk %}">
{% csrf_token %}
{{ thing.name }}
{{ form.value }}
<input type="submit" value="Submit" />
</form>
{% endfor %}
The url tag does a reverse lookup through your urls for the name kwarg supplied for a given url, and accepting positional arguments (such as, in this case, thing.pk) and, when needed, keyword arguments.
The standard way to handle multiple forms of the same kind on one page with Django is to use Formsets.
It handles the annoying details like displaying errors on one form while preserving the input on others etc.
However, in your specific case that might be overkill. If you just want to create a like for an object, there isn't really any user input that needs to be validated, so you don't really need a form. Just perform a POST to a specified URL, maybe with Javascript. If the user messes with the URL, you display a 404.
I am trying to pass some dynamic values from my form, but so far I am only getting empty values.
I have an autocomplete plugin, where I search for "names" from a JSON object, each time I select one they will pass into a list with value="the ID".
I couldn't find a unordered list in WTForms, so I am using SelectMultipleField instead, since it is able to pass many values as an array/list
my form class is looking like this:
class ClassForm(Form):
function_name = StringField('names')
studentid = SelectMultipleField('studentid')
submit = SubmitField('submit')
then in my template I am using it like this
<form id="function_search_form" method="post" action="">
{{ form.csrf_token }}
{{form.function_name.label()}}
{{form.function_name()}}
<!-- then I am not using studentid directly,
but just normal html, so each time you pass
in a name from the json object it will come in like this.
-->
<ol class='student-list'>
<li value="1" name="studentid" id="studentid">test</li>
</ol>
{{ form.submit()}}
</form>
My problem is that it wont get the value from the list, even if I hard code the values directly, instead from the jquery script.
Here is how my view looks like
#app.route('/index', methods=['GET', 'POST'])
def index():
form = ClassForm()
if request.method == 'POST' and form.validate_on_submit():
flash('valid form')
st = form.studentid.data
print(st)#debug
return render_template('index.html', form=form)
Everytime I submit I am printing form.studentid.data I am getting [], which is an empty list.
Even when I try to pass single values and make studentid to a StringField I am still getting an empty value.
I have also tried the request.form['studentid'] but then I am getting Bad Request What am I doing wrong and is there another way to pass "custom" values ?
The reason its not working is because <li> is not a form control, so its data is not sent back with the form request.
You are never rendering the studentid field from your form class, so the form control is never rendered. It would be like expecting the following to work:
<form>
<p name="foo" data="hello">This should be sent</p>
<input type="submit">
</form>
To get the data back to your view method, you need to use a form control - you can test it out like this:
<form id="function_search_form" method="post" action="">
{{ form.csrf_token }}
{{form.function_name.label()}}
{{form.function_name()}}
<select name="studentid" class='student-list'>
<option value="1">test</option>
</select>
{{ form.submit()}}
</form>
Or, simply render the field correctly:
<form id="function_search_form" method="post" action="">
{{ form.csrf_token }}
{{form.function_name.label()}}
{{form.function_name()}}
{{form.studentid.label()}}
{{form.studentid}}
{{ form.submit()}}
</form>
There is template:
<form action="{% url 'nfoapp.views.kinoscrap' <I WANT MOVIE_ID THERE> selectshort.id %}" method="post">
<input type="text" class="form-control" name="MOVIE_ID">
<button type="submit" class="btn btn-danger">Kinopoisk Search by ID</button>
</form>
There is my urls.py:
(r'^kinoscrap/(?P<kinoid>\d+)/(?P<shortid>\d+)/$', kinoscrap),
I want pass to kinoscrap two parameters - text field from form (MOVIE_ID) and 'selectshort.id' variable. The problem is that i can't put simple MOVIE_ID in first line of template, I got error. But when I try put instead MOVIE_ID other variable, for example selectshort.id, program work without error.
How I can trasmit text field value to view?
p.s I use bootstrap, if it has some importance.
You could have the form action empty, so to the same view, and then in the view redirect using the POST data from the form.
<form action="" method="post">
<input type="text" class="form-control" name="MOVIE_ID">
<button type="submit" class="btn btn-danger">Kinopoisk Search by ID</button>
</form>
And then in the view
def searchView(request):
if request.method == 'POST':
# get variables from form and redirect
else:
# do your normal rendering
(r'^kinoscrap/(?P<kinoid>\d+)/(?P<shortid>\d+)/$', kinoscrap),
Your urls.py accepts to integer values in the url (something like kinnoscrap/12/21), if you pass anything beside integers it'll throw an error. If you want to pass a text field you'll have to change the regular expression.
Try out your regexes at regex101 here to see if they'll work.