i selected a country from a screener function, send this form again to screener function
screenshot
The problem, my form don't keep the last selected country in my form (the variable "country" is send ). I always have the value 'Any' in the form
my list for select
example i
id=1 => 'France'
id=2 => 'Japan'... so if a choose Japan, (id=2) [2]i want to see Japan and not "Any" in the form
[enter image description here]
your help would be appreciated
thank you
screener.html
<form method=POST action="{{ url_for('screener') }}" onchange=submit()>
<table class="table table-sm table-hover">
<thead>
<tr><td>control : {{ country }}</td></tr>
<tr>
<td>Country</td>
<td>
<select id="country" name="country" class="form-select form-select-sm" aria-label="">
<option value="">Any</option>
{% for db_country in db_countries %}
<option value="{{ db_country.id }}" {% if country == db_country.id %} selected {% endif %} >
{{ db_country.id }} - {{ db_country.name }}`</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
</table>
</form>
app.py
`#app.route('/screener/', methods=['POST', 'GET'])
def screener():
db_countries = Country.query.order_by(Country.name.asc()).all()
if request.method == 'POST':
country = request.form['country']
else:
country = 0
return render_template('screener.html', title='Screener',db_countries=db_countries, country=country)`
You are comparing a str to an int. For this reason, the comparison fails.
Change the variable country to an int and it works.
Either you change the type in the endpoint
country = request.form.get('country', 0, type=int)
or in the template.
{% if country | int == db_country.id %} selected {% endif %}
Related
I have a page in my Flask app where the user can query the last 10, 25, 50, or 100 entries of a table. I want the dropdown default selection to display the number of entries that the user has chosen. So if they decided that they want to display 50 entries, the option 50 would be selected in the dropdown menu.
I think I'm close, but my code below isn't doing what I'm aiming for:
app.py:
class log_db(db.Model):
id = db.Column(db.Integer, primary_key=True)
carrier = db.Column(db.String(100), nullable=False)
#app.route('/history', methods=['GET'])
def history():
if not request.args.get('log'):
query_limit = "10"
else:
query_limit = request.args.get('log')
log = log_db.query.order_by(log_db.id.desc()).limit(query_limit).all()
return render_template('history.html', log=log)
history.html:
<form class="form">
<label for="log">Number of change log entries to query:</label>
<select name="log" id="log_query">
<option value="10"
{% if query_limit == 10 %} selected {% endif %}>10</option>
<option value="25"
{% if query_limit == 25 %} selected {% endif %}>25</option>
<option value="50"
{% if query_limit == 50 %} selected {% endif %}>50</option>
<option value="100"
{% if query_limit == 100 %} selected {% endif %}>100</option>
</select><br><br>
<input type="submit" value="Update View" class="create_edit">
</form>
In your render_template return you are not passing the "query_limit". Take care with compare string and integers it could not work.
I edited the code and got it to work. I passed query_limit to history.html and put quotes around each number in the select tag.
app.py
#app.route('/history', methods=['GET'])
def history():
if not request.args.get('log'):
query_limit = "10"
else:
query_limit = request.args.get('log')
log = log_db.query.order_by(log_db.id.desc()).limit(query_limit).all()
return render_template('history.html', log=log, query_limit=query_limit)
history.html
<form class="form">
<label for="log">Number of change log entries to query:</label>
<select name="log" id="log_query">
<option value="10"
{% if query_limit == "10" %} selected {% endif %}>10</option>
<option value="25"
{% if query_limit == "25" %} selected {% endif %}>25</option>
<option value="50"
{% if query_limit == "50" %} selected {% endif %}>50</option>
<option value="100"
{% if query_limit == "100" %} selected {% endif %}>100</option>
</select><br><br>
<input type="submit" value="Update View" class="create_edit">
</form>
I currently have an app that is meant to generate documents based on user-set settings. The settings are supposed to be read by the program based on the class's instance settings so that the program knows which setting it is generating documents for.
When creating the instance settings for the user to edit each model entry, the code works like this:
setting = get_object_or_404(SettingsClass, pk=setting_pk)
if request.method == 'GET':
form = SettingUpdateForm(instance=setting)
return render(request, 'main/viewSettings.html', {'setting': setting, 'form':form})
else:
form = SettingUpdateForm(request.POST, instance=setting)
if form.is_valid():
form.save()
return redirect('settingsHome')
So it uses the "get_object_or_404" function to return the instance that the user should be working in and tells the form to use that instance here :form = SettingUpdateForm(instance=setting)
However when I am trying to execute this while reading from the model , the same type of setup does not work. This is what I have set up in my views at the moment:
def printReports(request , reports_pk):
pkForm = get_object_or_404(SettingsClass , pk=reports_pk)
form= SettingsClass(instance=pkForm)
complexName = form.Complex
I am basically trying to tell the program to work in a certain instance of the model and read items from there, like: complexName = form.Complex
If anyone has any solution or alternate way to setup something like this , please assist. I will add the my URLs, templates and views code below for better viewing
Views.py:
def reportsHome(request):
model = SettingsClass.objects.all().order_by('Complex')
content ={'model':model }
return render(request, 'main/reportsHome.html' , content)
def printReports(request , reports_pk):
pkForm = get_object_or_404(SettingsClass , pk=reports_pk)
form= SettingsClass(instance=pkForm)
complexName = form.Complex
#CHECKING TRIAL BALANCE SETTINGS
if form.Trial_balance_Year_to_date == True:
printTrialBalanceYTD = True
### Printing Trial Balance PDF
response = HttpResponse(content_type= 'application/pdf')
response['Content-Disposition']= 'attachment; filename=TrialBalance' + \
str(datetime.now()) + '.pdf'
response['Content-Transfer-Encoding'] = 'binary'
#SQL STATEMENT
baseSelect = 'SELECT '+ op5 + op4 + ' Debit , Credit FROM [?].[dbo].[PostGL] AS genLedger '
xtrbYTD = baseSelect + trbYTD + op1 + op2 + op3 + op6
cursor = cnxn.cursor();
cursor.execute(baseTRBYear, [complexName], [complexName], [complexName], [one_yrs_ago]);
xAll = cursor.fetchall()
cursor.close()
xtrbYTD = []
for row in xtrbYTD:
rdict = {}
rdict["Description"] = row[0]
rdict["Account"] = row[1]
rdict["Debit"] = row[2]
rdict["Credit"] = row[3]
arr_trbYTD.append(rdict)
content = {"arr_trbYTD":arr_trbYTD , 'xCreditTotal':xCreditTotal , 'xDebitTotal':xDebitTotal , 'complexName':complexName , 'openingBalances': openingBalances ,'printZero':printZero}
html_string=render_to_string('main/pdf-trialbalance.html' , content)
html=HTML(string=html_string)
result=html.write_pdf()
with tempfile.NamedTemporaryFile(delete=True) as output:
output.write(result)
output.flush()
output.seek(0)
response.write(output.read())
return response
else:
printTrialBalanceYTD = False
urls.py:
#Reports
path('accConnect' , views.reportsHome, name='reportsHome'),
path('accConnect/printReports/<int:reports_pk>' , views.printReports , name='printReports')
TEMPLATES:
reportsHome.html:
{% block content%}
<h1 style=" text-align: center">Reports</h1>
<hr>
<br>
<div class="list-group">
<a href="#" class='list-group-item active'>Print Single Complex's</a>
{% for x in model %}
<a href="{% url 'printReports' %}" class="list-group-item list-group-item-action" >{{ x.Complex }} Reports</a>
{% endfor %}
</div>
{% endblock %}
pdf-trialbalance.html:
{% block content%}
<h1 class = 'center'>Kyle Database Trial Balance</h1>
<br>
</div>
<br>
<br>
<div class="table-container">
<table style="width: 100%">
<th >Account</th>
<th>Description</th>
<th>Debit</th>
<th>Credit</th>
{% for arr_trbYTD in arr_trbYTD %}
<tr>
<td>{{ arr_trbYTD.Description }}</td>
<td>{{ arr_trbYTD.Account }}</td>
<td>
{%if arr_trbYTD.Debit > 0%}
{{arr_trbYTD.Debit}}
{%endif%}
</td>
<td>
{%if arr_trbYTD.Credit > 0%}
{{arr_trbYTD.Credit}}
{%endif%}
</td>
</tr>
<tr >
{% endfor %}
<td> <b>Totals</b> </td>
<td> </td>
{% for xDebitTotal in xDebitTotal %}
<td><b>R {{ xDebitTotal }}</b></td>
{% endfor %}
{% for xCreditTotal in xCreditTotal %}
<td><b>R {{ xCreditTotal }}</b></td>
{% endfor %}
</tr>
</table>
</div>
<br>
<br>
<br>
{% endblock %}
To solve the error in the title, first you need to fix the usage of url in the template and pass the primary key of the SettingsClass instance with:
{% url 'printReports' x.pk %}
So:
{% for x in model %}
<a href="{% url 'printReports' x.pk %}" class="list-group-item list-group-item-action" >{{ x.Complex }} Reports</a>
{% endfor %}
And then in your view, you don't need to use a form to access the attributes from your SettingsClass instance, so you can just do something like:
def printReports(request , reports_pk):
settings_instance = get_object_or_404(SettingsClass , pk=reports_pk)
complexName = settings_instance.Complex
#CHECKING TRIAL BALANCE SETTINGS
if settings_instance.Trial_balance_Year_to_date == True:
...
You are not passing the "reports" variable to context. that's why the PK value is empty. check the view that's rendering reportsHome.html and apply the necessary, variable to template eg:
def view_func(request)
......
return render(request, '<template_name>.html', {"report": report })
This is my models.py file.
class CustomerInfo(models.Model):
customer_name=models.CharField('Customer Name', max_length=50)
customer_mobile_no = models.CharField('Mobile No', null=True, blank=True,max_length=12)
customer_price=models.IntegerField('Customer Price')
customer_product_warrenty = models.CharField('Product Warrenty',null=True, blank=True,max_length=10)
customer_sell_date = models.DateTimeField('date-published', auto_now=True)
customer_product_id=models.CharField('Product ID',max_length=150,null=True, blank=True)
customer_product_name=models.CharField('Product Name', max_length=50)
customer_product_quantity=models.IntegerField('Quantity',default=1)
def __str__(self):
return self.customer_name
Now I want to search in muliple fieds like as customer_name, customer_mobile_no,customer_product_id etc. So I created views.py file
def customerPage(request):
customers = CustomerInfo.objects.all()
if request.method =="GET":
customerid = request.GET['customer_id']
try:
customers = CustomerInfo.objects.get(pk=customerid)
cus_name = CustomerInfo.objects.filter(customer_name__contains=customerid)
mobile_number = CustomerInfo.objects.filter(customer_mobile_no__contains=customerid)
return render(request, 'shop/customer.html', {"cus_name": cus_name,"mobile_number": mobile_number, "customers": 'customers', "site_name": "Moon Telecom"})
except:
return render(request, 'shop/customer.html', {"error": "Not found any info"})
return render(request, 'shop/customer.html', {'customers': customers})
and this is my html file
{% extends "shop/base.html" %}
{% block content_area %}
<div class="col-lg-4">
<div class="customer_search" >
<form action="{% url "shop:customerPage" %}" method="GET">
{% csrf_token %}
<div class="form-group">
<label for="customer_id">Id:</label>
<input type="text" class="form-control" id="customer_id" placeholder="Enter customer ID" name="customer_id">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="col-lg-8 customers_info">
{% if error %}
<div class="alert alert-danger">
<strong>{{error}}</strong>
</div>
{% endif %}
{% if cus_name %}
{% for x in cus_name %}
<p>{{x.customer_name}}</p>
{% endfor %}
{% else %}
<p>nothing foung</p>
{% endif %}
{% if customers %}
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Mobile No</th>
<th>Product Name</th>
<th>Price</th>
<th>Date</th>
<th>Product ID</th>
<th>Warrenty</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{customers.customer_name}}</td>
<td>{{customers.customer_mobile_no}}</td>
<td>{{customers.customer_product_name}}</td>
<td>{{customers.customer_price}} TK</td>
<td>{{customers.customer_sell_date}}</td>
<td>{{customers.customer_product_id}}</td>
<td>{% if customers.customer_product_warrenty == '' %}
<b>No Warrenty</b>
{% else %}
<b>{{customers.customer_product_warrenty}}</b> Month
{% endif %}
</td>
</tr>
</tbody>
</table>
{% else %}
<p>nothing found</p>
{% endif %}
</div>
{% endblock %}
I got results If I use POST method and customers = CustomerInfo.objects.get(pk=customerid) When I searched one field, I have got my results but When I start multiple search query from the database. I cant get any info. I want to search multiple fields within CustomerInfo model. Also, I was trying others mehtod but not working.
You need to search using multiple fields in one query. And looking at your code, i presume that the conditions are joined using OR.
This problem can be solved using django ORM's Q object
What it allows you do is to chain multiple filtering conditions together and connect them logically.
So, if you have 3 conditions and they are logically connected as :
Condition 1 OR Condition 2 AND Condition 3 using Q you can write them as :
Q(Condition1) | Q(Conditon2) & Q(Condition2).
In your case the 3 different searches of filterings can be performed as:
filtered_customers = CustomerInfo.objects.filter( Q(pk = int(customerid)) | Q(customer_name__contains = str(customerid)) | Q(customer_mobile_no__contains = str(customerid)))
I'm trying to get the users that I'm marking as True on my website in data['checked_users']:
models.py
class Player(models.Model):
jucator = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, related_name='jucator')
porecla = models.CharField(max_length=50, null=True, blank=True)
selectat = models.BooleanField(default=False)
def __str__(self):
return u'%s' % self.jucator
views.py
def check_user(request):
data = dict()
data['players'] = Player.objects.all()
if request.method == 'POST':
list_of_checks = request.POST.getlist('checks[]')
# data['checked_users'] = list_of_checks
data['checked_users'] = Player.objects.filter(jucator__in=list_of_checks)
return render(request, 'checkbox.html', data)
checkbox.html
<body>
{% block content %}
<form action="" method="POST">{% csrf_token %}
<table>
{% if request.user.is_superuser %}
{% for user in players %}
<tr>
<td><input type="checkbox" name="checks[]" value="{{ user.jucator }}" title="selected_players">{{ user.jucator }}<br></td>
</tr>
{% endfor %}
<tr>
<td><input type="submit" name="submit" value="Submit"></td>
</tr>
{% else %}
{% for user in players %}
<tr><td>{{ user.jucator }}</td></tr>
{% endfor %}
{% endif %}
</table>
{% for player in checked_users %}
{{ player }}
{% endfor %}
</form>
{% endblock %}
</body>
If I try this, it shows the players:
data['checked_users'] = list_of_checks
If I try with filter, I get this error:
invalid literal for int() with base 10: 'Stalone'
You need to put inside value="{{ user.jucator }}" the actual id of the jucator object. Not the jucator object itself.
So, change to this: value="{{ user.jucator.id }}". Now you can query with Player.objects.filter(jucator__in=list_of_checks) since list_of_checks containts a list of integers (the ids of jucators).
If this is the view in Django_notification (https://github.com/pinax/django-notification/blob/master/notification/views.py), how do I display the check box? It doesn't seem like there are form objects here. Usually, I'm used to doing this: {{ myform.thefield }}
#login_required
def notice_settings(request):
"""
The notice settings view.
Template: :template:`notification/notice_settings.html`
Context:
notice_types
A list of all :model:`notification.NoticeType` objects.
notice_settings
A dictionary containing ``column_headers`` for each ``NOTICE_MEDIA``
and ``rows`` containing a list of dictionaries: ``notice_type``, a
:model:`notification.NoticeType` object and ``cells``, a list of
tuples whose first value is suitable for use in forms and the second
value is ``True`` or ``False`` depending on a ``request.POST``
variable called ``form_label``, whose valid value is ``on``.
"""
notice_types = NoticeType.objects.all()
settings_table = []
for notice_type in notice_types:
settings_row = []
for medium_id, medium_display in NOTICE_MEDIA:
form_label = "%s_%s" % (notice_type.label, medium_id)
setting = get_notification_setting(request.user, notice_type, medium_id)
if request.method == "POST":
if request.POST.get(form_label) == "on":
if not setting.send:
setting.send = True
setting.save()
else:
if setting.send:
setting.send = False
setting.save()
settings_row.append((form_label, setting.send))
settings_table.append({"notice_type": notice_type, "cells": settings_row})
if request.method == "POST":
next_page = request.POST.get("next_page", ".")
return HttpResponseRedirect(next_page)
notice_settings = {
"column_headers": [medium_display for medium_id, medium_display in NOTICE_MEDIA],
"rows": settings_table,
}
return render_to_response("notification/notice_settings.html", {
"notice_types": notice_types,
"notice_settings": notice_settings,
}, context_instance=RequestContext(request))
The default template for this view is checked into github: https://github.com/pinax/pinax/blob/master/pinax/templates/default/notification/notice_settings.html
UPDATE: Pinax removed their themes, the last checkin with templates can still be found here.
There is no form defined for the notification settings object, so the checkbox elements (and the form itself) are created using raw HTML:
<form method="POST" action=""> {# doubt this easy to do in uni-form #}
{% csrf_token %}
<table class="notice_settings">
<tr>
<th>{% trans "Notification Type" %}</th>
{% for header in notice_settings.column_headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for row in notice_settings.rows %}
<tr>
<td>{% trans row.notice_type.display %}<br/>
<span class="notice_type_description">{% trans row.notice_type.description %}</span>
</td>
{% for cell in row.cells %}
<td>
<input type="checkbox" name="{{ cell.0 }}" {% if cell.1 %}checked="yes"{% endif %}/>
</td>
{% endfor %}
</tr>
{% endfor %}
<tr>
<td><input type="submit" value="{% trans "Change" %}" /></td>
</tr>
</table>
</form>
The view you show only manages the processing of the POSTed notification but not the displaying of a form in a page. You can create your own form that includes a field called form_label and include it in whatever page that posts to this view (could be a hidden input).