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>
Related
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.
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)
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!
I have code:
<select class="form-control" id="engine" name="engine">
{% for engine in engines %}
<option name="{{engine.id}}">{{engine.name}}</option>
{% endfor %}
</select>
print request.POST:
<QueryDict: {u'engine': [u'test1'], u'csrfmiddlewaretoken': [u'9rICLe2X1m0KBnxLjY7V2gYoeV5Dd3m6']}>
I want get id in "engine"(not value). How I can do it?
Change this line <option name="{{engine.id}}">{{engine.name}}</option> to:
<option value="{{engine.id}}">{{engine.name}}</option>
What do you mean by
I want get id in "engine"(not value)
You mean in your view? Isn't that simply
request.POST['engine']
Trying to optimize a django application which is using 1.3. Migrating to latest django is not yet an option, as it's a huge application.
So there's this code in the template:
<select id="item_product">
{% for ip in items %}
<option value="{{ ip.program.id }}/{{ ip.sector.id }}/">{{ ip }}</option>
{% endfor %}
</select>
This seems to generate DB calls for every option - making it pretty slow to just load a page with just a drop-down and a button! Replacing the option values with dummy strings indeed immediately loads the page.
The view is very simple:
#render_to('pick_item.html')
def pick_item(request):
person = request.user.get_profile()
items = ItemProduct.objects.filter(program__in=person.programs)
return {'items': items }
And this code returns pretty fast.
How can I optimize this code for django 1.3 so that the drop-down options have the ids I need more efficiently?
If you only need ID's:
<select id="item_product">
{% for ip in items %}
<option value="{{ ip.program_id }}/{{ ip.sector_id }}/">{{ ip }}</option>
{% endfor %}
</select>
If you need something more complex:
#render_to('pick_item.html')
def pick_item(request):
person = request.user.get_profile()
items = ItemProduct.objects.filter(program__in=person.programs).select_related('program', 'sector')
return {'items': items }