Django custom form template - python

I've a custom template to render my form in my Django website. This code renders the ChoiceFields:
<select id="{{ "id_"|add:field.html_name }}"
class="form-control"
name="{{ field.html_name }}">
{% for id, name in field.field.choices %}
<option value="{{ id }}"
{% if field.value|default_if_none:"" == id %}
selected="selected"
{% endif %}
>{{ name }}</option>
{% endfor %}
</select>
This code works perfectly, when the ChoiceField does not have an initial value. If I sumbit the form, but there's an error in the form (sp I get back to my form, and all the data is in there as I submitted it), the correct choice get the selected="selected" attribute, so it works perfectly fine.
But when I set the default value for the form in my Django view (correctly in the form's init() function, like this: self.fields['card_type'].initial = self.card.card_type_id), this stops working.
If I put manually somewhere in my template the form.value variable it displays the correct integer. In the id, name for-loop there's the same id value. These do not have any whitespace ot something else there. But the code does not works, does not equals to true the self.fields['card_type'].initial = self.card.card_type_id condition.
If I modify the previous code, to print the id, and the field.value instead of the {{name}}, like this: ({{id}}-{{ field.value }}), the following HTML code'll be generated:
<select id="id_card_type" class="form-control" name="card_type">
<option value="3">(3-2)</option>
<option value="2">(2-2)</option>
<option value="1">(1-2)</option>
</select>
There's the id, which is 1, 2, and 3! There's the form.value, which is 2! But there isn't any selected="selected"... Why not working?
Thanks!

Related

Set "selected" tag in responsive dropdown and select using Flask and jinja2

I have a flask server which sends a dictionary of options to a dropdown or selection (in form).
Here is the Python code:
#app.route("/", methods=['GET'])
def index_get():
options = {'o1' : 'option1', 'o2' : 'option2', 'o3' : 'option3'}
return flask.render_template("index.html", options=options)
This is the Jinja code:
<form method="post">
<select name="test">
{% for id,name in options.items() %}
<option selected="" value="{{ id }}">{{name|safe}}</option>
{% endfor %}
</select>
</from>
Now, I want to set the selected attribute to one of the option, for example, option2 from the Python code like return flask.render_template("index.html", options=options, selected='option2') or selected='o2'.
Can someone help me implementing this?
Once you have passed your desired options to the view, via
return flask.render_template("index.html", options=options, selected='o2')
You just have to make a condition that would assert if the selected variable is the same as the current id in the loop, in order to add the selected attribute to the option or not:
<form method="post">
<select name="test">
{% for id,name in options.items() %}
<option {% if selected == id %}selected{% endif %} value="{{ id }}">
{{name|safe}}
</option>
{% endfor %}
</select>
</from>

Data is not appearing on HTML... it is showing empty instead

I have created a Database and also create a form to add data in it.
But when I try to show the data on html it shows nothing.
My Model is
class Bank(models.Model):
bankname=models.CharField(max_length=50)
acctitle=models.CharField(max_length=50)
city=models.CharField(max_length=50)
branchname=models.CharField(max_length=50, null=True)
branchcode=models.IntegerField(default=0)
adddate=models.DateTimeField(default=timezone.now)
def __str__(self):
return self.bankname
My Views
def add_bank(request):
if request.method=='POST':
bankname=request.POST.get('bankname')
acctitle=request.POST.get('acctitle')
city=request.POST.get('city')
branchname=request.POST.get('branchname')
branchcode=request.POST.get('branchcode')
data=Bank(bankname=bankname,acctitle=acctitle,city=city,branchname=branchname, branchcode=branchcode)
data.save();
return render(request, 'add_bank.html')
def add_amount(request):
banks= Bank.objects.all()
return render(request, 'add_amount.html', {'banks':banks})
My Html for displaying data
<select name="banks" class="form-control custom-select">
<option value="">Bank:</option>
{% for bank in banks %}
<option value="{{ forloop.counter }}">{{ banks.bankname }}</option>
{% endfor %}
</select>
Output Image
I don't know where I'm making mistake
Change banks.bankname to bank.bankname in this line:
<option value="{{ forloop.counter }}">{{ banks.bankname }}</option>
To understand why this didn't result in an error, you can refer this.
You are using a for loop in which every item (object) of the banks model is referred to as a bank by you in a loop. So use "bank.bankname".
eg.
<option value="{{ forloop.counter }}">{{ bank.bankname }}</option>
Also, As the best practice try to use your table's primary key in value in the Option tag. This will help you for better reference to the particular data (tables object) in javascript for sending data to views.
eg.
<option value="{{ bank.banks_primary_key }}">{{ bank.bankname }}</option>

Problem with select and request.form.get and getlist in Flask

My problem is not that serious, just a little bit annoying. I have a dropdown menu and a list of values; however, my values resets themselves to the first option, and I would like for them to remain as the user selected them.
I have read from other sources that the solution is using getlist instead of get, but when I attempt to do it, I get the following error:
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
I have little experience working with flask and Jinga. I guess this must be a problem with the type of values, or some type of name or value that I need to fetch... I honestly have no idea. Any help will be appreciated.
Here is the video of how the flask is working with request.form.get, and here is the code that I have for that specific html view and the fragment of the app where I am requesting the data.
#app.route('/apuntual', methods = ['GET','POST'])
def apunt():
if request.method == 'POST':
# This is the button that I click on the video
if request.form.get('capturar') == 'capturar':
sample_rate_unf = request.form.get('f_muestreo')
samples_to_acq_unf = request.form.get('m_canal')
#Changing the values to int so I can work with them
sample_rate = int(sample_rate_unf)
samples_to_acq = int(samples_to_acq_unf)
#lots of more code in here
#
# Sending the output values to make the graph, and some other values to
# display in the html
return render_template('apuntual.html', fmax = fmax, tad = tad, imagen = datos)
<div class="col-md-2">
<form method="POST">
<h5 class="mb-1">Frecuencia de muestreo</h5>
<select name="f_muestreo">
<option value="2048">2048</option>
<option value="2560">2560</option>
<option value="3200">3200</option>
<option value="5120">5120</option>
</select>
<h5 class="mb-1">Muestras por canal</h5>
<select name="m_canal">
<option value="2048">2048</option>
<option value="4096">4096</option>
<option value="8192">8192</option>
</select>
<h5 class="mb-1">Captura instantánea</h5>
<p class="bs-component">
<input type="submit" class="btn btn-primary" name="capturar" value="capturar">
<input type="submit" class="btn btn-primary" name="borrar" value="borrar">
</p>
<p class=""bs-component>Frecuencia máxima de: {{ fmax }} Hz con TAD: {{ tad }} ms.</p>
</form>
</div>
One solution I can think of is to pass the selected option as a variable to the template and mark the selected option in the template. Here is a demo:
#app.route("/", methods=("GET", "POST"))
def demo():
options = (1, 2, 3, 4)
selected = None
if request.method == "POST":
selected = int(request.form.get("something"))
# Rest of the code goes here
return render_template("demo.html", options=options, selected=selected)
<form method="POST">
<select name="something">
{% for op in options %}
{% if selected == op %}
<option value="{{ op }}" selected>{{ op }}</option>
{% else %}
<option value="{{ op }}">{{ op }}</option>
{% endif %}
{% endfor $}
</select>
<input type="submit">
</form>
Notice that I put all the options as a tuple in the server code. One of reason is to avoid repetitions in the template code. It is also generally considered a bad practice to store data directly to the frontend code like what you are doing here. My demo is not perfect either. A better solution is to put all these options into a configuration file.

can i do process with form django python

there is a input and select with options in form tag. i want to get input value and option that entered. and i will do somethings on backend with python that value and option than i will return a result to website. but i dont use to forms.py. how can i do? is it possible?
<form action="" method="post">
{% csrf_token %}
<input type="text" name="getinputValue">
<select name="">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
</select>
<button type=""class=""></button>
<p>{{result}}</p>
</form>
So, from what I understanding in your question, you want to retrieve the data from the form in your views and do something with it. You will have to give your <select> a name attribute so that you can reference it in your views.
<select name="level">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
</select>
In your views, one of the ways you can retrieve this data is by:
def options_view(request):
level = request.POST.get('level') # get name of option as specified in the <select> tag
# here you can do something with it
print(level)
return render(request, 'home.html', {'level': level})
This is one way to do it.

Return the string value of what is selected in the drop down list

I have a list of stops:
<select name="dropdown">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
and a Stops model where one of the attributes is name.
I also have a method find_direction() in my views.py that requires a stop.location input.
How do I record the value of the selected stop.name so I can then get the stop.location to use in views.py?
Thanks!
Currently my method is:
def find_direction(request, stop1name, stop2name):
stop1 = get_object_or_404(Stops, name=stop1name)
stop2 = get_object_or_404(Stops, name=stop2name)
which gives the error: find_direction() missing 2 required positional arguments: 'stop1' and 'stop2name'.. How do I make it record these two variables correctly from the selected drop down list?
Using forms but for some reason..
print(request.GET.get("stop1id", "default_value"))
print(request.GET.get("stop2id", "default_value"))
print(request.method)
print(request.POST.dict())
print(request.GET.dict())
print(request.body)
all return empty
In light of your update, you will most like want to pass the data in a request:
def find_direction(request):
stop1 = get_object_or_404(Stops, name=request.POST.get("stop1name","default_value"))
stop2 = get_object_or_404(Stops, name=request.POST.get("stop2name","default_value"))
This assumes you are sending a POST request from a form back to the server with the stop name data. The dictionary keys stop1name and stop2name should match the names as they are set in your form:
<form action="/get_stop_locations">
<select name="stop1name">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
<select name="stop2name">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
</form>
If you are curious, you were receiving an error because positional arguments for django views are set up as captured bits of a url:
urls.py
urlpatterns = patterns('django_app.views',
url(r'^get_stop_locations/(\w+)/(\w+)$','positional_get_locations'),
)
views.py
def positional_get_locations(request,stop1name,stop2name):
stop1 = get_object_or_404(Stops, name=stop1name)
stop2 = get_object_or_404(Stops, name=stop2name)
Django views requires one argument by default which will store the request object. When there are more views defined, the view expects more arguments to be provided by the url handler. If the url is not set up to pull as many arguments as possible in your urls.py file, you will see this error.
For your case, this requires setting up some tricky URLs however on the client side and I wouldn't recommend it. See this example in the DJango Docs for more information on positional arguments in Django views.
EDIT:
In response to your MultiValueDictKeyError, try:
def find_direction(request):
stop1 = get_object_or_404(Stops, name=request.POST.get("stop1name","default_value"))
stop2 = get_object_or_404(Stops, name=request.POST.get("stop2name","default_value"))
If you have your dropdown located in a form like this:
<form method="post" action="">
<select name="dropdown">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
<input type="submit" />
</form>
You can get the value by defining the following in your views:
def post(self, request, *args, **kwargs):
if 'dropdown' in request.POST:
dropdown_val = request.POST.get('dropdown', False)

Categories

Resources