Passing data from django form to ListView - python-3.x

Above is an image of what I am attempting to build: A form that is at the top while the area to display a result list is below. When I hit 'Go!', the part below does not render the list as I hoped. Also, I am not sure if this is the 'proper' way to go about doing this.
The Class Based View that i use:
class EntryListView(ListView):
template_name = 'finance/entry_list.html'
now = datetime.now()
year = now.year
context_object_name = 'entry_list'
model = Entry
paginate_by = 10
month_list = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
'November', 'December']
year_list = list(range(Entry.objects.earliest('input_date').input_date.year,
Entry.objects.latest('input_date').input_date.year))
def get_context_data(self, **kwargs):
context = super(EntryListView, self).get_context_data(**kwargs)
# https://stackoverflow.com/questions/18232851/django-passing-variables-to-templates-from-class-based-views
context.update({
'month_list': self.month_list,
'year_list': self.year_list,
})
return context
# This method ensures that I can customize the list of entries returned.
def get_queryset(self):
# https://stackoverflow.com/questions/22902457/django-listview-customising-queryset
if self.request.method == 'GET':
print('I have entered here!')
month = self.request.GET.get('month')
year = self.request.GET.get('year')
print('month: ' + str(month))
print('year: ' + str(year))
if month or year is None:
return Entry.objects.filter(input_date__month=datetime.now().month,
input_date__year=datetime.now().year).order_by('-input_date').all()
else:
return Entry.objects.filter(input_date__month=month,
input_date__year=year).order_by('-input_date').all()
Here is my urls.py:
url(r'entry/$', login_required(views.EntryListView.as_view()), name='list_entries'),
The EntryListView is also in charged of ensuring that the form is populated with the right 'Dropdown values'.
And here is the template:
{% extends 'base.html' %}
{% block body_content %}
<div class="wrapper">
{% include 'finance/finance_sidebar.html' %} <!-- Add this for inheritance -->
<div class="container">
<div class="row">
<form class="well contact-form" method='GET'>
<label>Month:</label>
<select class="well form-control" name="month">
{% for month in month_list %}
<option value="{{ forloop.counter }}">{{ month }}</option>
{% endfor %}
</select>
<label>Year:</label>
<select class="well form-control" name="year">
{% for year in year_list %}
<option value="{{ year }}">{{ year }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-default">Go!</button>
</form>
</div>
<div class="row">
{% if entry_list %}
<div class="container">
<table class="table table-hover">
<thead>
<tr>
<th>No.</th>
<th width="100">Input Date</th>
<th>Category</th>
<th>Tag</th>
<th>Description</th>
<th>Value</th>
<th>Transfer Type</th>
<th>Remarks</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for entry in entry_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ entry.input_date|date:'d M Y' }}</td>
<td>{{ entry.category }}</td>
<td>{{ entry.tag }}</td>
<td>{{ entry.description }}</td>
<td>${{ entry.value }}</td>
<td>{{ entry.transfer_type }}</td>
<td>{{ entry.remarks }}</td>
<td>
<form class="flex-container" method="post" action="{% url 'finance:update_entry' pk=entry.id %}" >
{% csrf_token %}
<div class="input-group">
<input type="hidden" name="id" value="{{ entry.id }}">
<button name="update" type="submit" class="btn btn-warning">EDIT </button>
</div>
</form>
</td>
<td>
<form class="flex-container" method="post" action="{% url 'finance:delete_entry' %}" >
{% csrf_token %}
<div class="input-group">
<input type="hidden" name="id" value="{{ entry.id }}">
<button name="delete" type="submit" class="btn btn-danger">DELETE </button>
</div>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="col-sm-7 col-sm-offset-5">
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
previous
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_page }}.
</span>
{% if page_obj.has_next %}
next
{% endif %}
</span>
</div>
{% endif %}
</div>
{% else %}
<p>Please make sure you have specified a month and the year.</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
I am again, not sure if this is the right way to approach it. I have seen something called Mixins, but I have no clue how to use them. I did a little print statements while debugging and i found that the data from the forms indeed are able to be accessed inside the get_queryset() method. I also made sure that my DB had such a record and i even typed it in my python shell to be sure that the query is not faulty.

Your if-else statement in your view is wrong. if month or year is None: will always evaluate to true since it can be rewritten as if (month) or (year is None) and you are actually posting month value to your view.
Instead, you could rewrite it as: if month is None or year is None:.

Related

In Django website even if I add an item by pressing add to cart button the status of True for the product added is not shown and still false is visibl

I have made a django e-comm website , when I press the add to cart button on my home page I have written a function which should change the status of a product from false to true once it is added in the cart but it does not work
I have given my cart.py and index.html code
Thank you
cart.py
from django import template
register = template.Library()
#register.filter(name='is_in_cart')
def is_in_cart(product,cart):
keys = cart.keys()
for id in keys:
print(id , product.id)
if int(id) == product.id:
return True
return False
index.html
{% extends 'main/base.html'%}
{% block title %}
index
{% endblock %}
{% block content %}
{% load cart %}
<div class="container-fluid">
<div class="row">
<div class="col-lg-3">
<div class="list-group mt-3">
{% for items in category %}
{{items.Category_name}} <!--i first used a small c for category but it did not pick the words from my category.py fle-->
{% endfor %}
</div>
</div>
<div class="col-lg-9">
<div class="row">
{% for items in product %}
<div class="card mx-auto mb-3 mt-3" style="width: 18rem;">
<img class="card-img-top" src="{{items.product_image.url}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{items.product_name}}</h5>
<p class="card-text"><b>{{items.product_price}}</b></p>
<p class="card-text"><b>{{items.product_detail}}</b></p>
{{product | is_in_cart:request.session.cart }}
<form action="/" mthod="POST">
{% csrf_token %}
<input hidden type="text" name='product' value='{{items.id}}'>
<input href="#" type="submit" class="float-right btn btn-light border btn-sm" value="Add to Cart">
</form>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

How add space between two cards - bootstrap?

I was creating a simple blog page using Django. When I added cards for the articles it came like this
There is no space between the cards.
{% extends 'base.html' %}
{% block content %}
<div class="card mt-3" style="width: 100%;">
{% for post in posts %}
<div class="card-header">
<cite title="Source Title">{{ post.author }}</cite>
<small class="text-muted float-right">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<p class="card-text">{{ post.content }}</p>
</div>
{% endfor %}
</div>
{% endblock content %}
How do I add space between these cards?
your for loop is not in correct place change code from
{% extends 'base.html' %}
{% block content %}
<div class="card mt-3" style="width: 100%;">
{% for post in posts %}
<div class="card-header">
<cite title="Source Title">{{ post.author }}</cite>
<small class="text-muted float-right">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<p class="card-text">{{ post.content }}</p>
</div>
{% endfor %}
</div>
{% endblock content %}
to bellow code
{% extends 'base.html' %}
{% block content %}
{% for post in posts %}
<div class="card mt-3" style="width: 100%;">
<div class="card-header">
<cite title="Source Title">{{ post.author }}</cite>
<small class="text-muted float-right">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<p class="card-text">{{ post.content }}</p>
</div>
</div>
{% endfor %}
{% endblock content %}
Firstly, you need to do the loop for every card, instead of doing it for the inner divs 'card-header' and 'card-body'. Secondly, to answer you question, you should use a spacing by either a margin or a padding.
I would suggest to make the cards a standard width and use a 'margin right 3':
{% for post in posts %}
<div class="card mt-3 mr-3" style="width: 250px">
<div class="card-header">
...
</div>
<div class="card-body">
...
</div>
</div>
{% endfor %}
Besides this solution, I suggest you read the Bootstaps Grid Layout documentation, so you can place the cards nicely within your content block.

Edit and Update Method is Not working

My problem is, edit and update the values by using python-flask from client side. I don't have any idea about that and new python-flask using MySQL database. I tried this method for edit and update purpose.But, it's not working.Additionally the details will be added in database when we enter details and submit. anyone help me.
Here is vehicletype.html template.
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Vehicletype > Create Vehicletype</li>
</ol>
</div>
<div class="row">
<div class="col-md-6">
<form role="form" action="/post/vehicletype" method="post">
<div class="form-group">
<label>VehicleType: </label>
<input name="type" class="form-control" placeholder="enter vehicletype">
</div>
<input type="submit" class="btn btn-primary" value="Submit ">
<input type="reset" class="btn btn-default" value="Reset">
</form>
</div>
</div>
{% endblock %}
Here is the details.html
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Vehicletype>View</li>
</ol>
</div><!--/.row-->
<div class="row">
<div class="col-md-12">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
Id
</th>
<th>
VehicleType
</th>
<th>
Dateofsub
</th>
<!--<th>
Control
</th>-->
<th>
Delete
</th>
</tr>
</thead>
{% for values in vehicletype %}
<tr>
<th>{{values.id}}</th>
<td>{{values.type}}</td>
<td>{{values.dateofsub}}</td>
<!--<td>Reset Password</td>-->
<td>Delete</td>
<td>edit</td>
</tr>
{% endfor %}
</table>
<em class="fa fa-xl fa-plus-circle color-blue" ></em>
</div>
</div>
{% endblock %}
python code for Edit method:
class VehicetypeForm(FlaskForm):
type=StringField('Type')
#app.route('/control/edit/<int:id>',methods=['POST','GET','PATCH'])
def edit(id):
form = VehicetypeForm(request.form)
mysql = pymysql.connect("0.0.0.0", "tnxt", "tnxt", "transport")
cur = mysql .cursor()
cur.execute('SELECT * FROM vehicletype WHERE id= %s',[id])
type=cur.fetchall()
# form.type.data=type
if request.method=='PATCH' and form.validate():
#type=form.type.data
mysql = pymysql.connect("0.0.0.0", "tnxt", "tnxt", "transport")
cur=pymysql .cursor()
cur.execute('UPDATE vehicletype SET type=%s WHERE id=%s',(type,id))
mysql.connection.commit()
cur.close()
flash('success')
return redirect(url_for('vehicle_type'))
return render_template('vehicletype.html',form=form)
In this python code update method is not working. But, when we give the details that details will be added in database. How to edit and update the values from client side.
Below is the good practice to create form using wtforms
class UserForm(Form):
name = StringField('Name')
father_name = StringField('Father Name')
# .... add fields you want
for field types - refer to this link
#app.route('/newuser', methods=['GET', 'POST'])
def add_user():
form = UserForm()
if form.validate_on_submit():
user_details = {
name: form.name.data,
fathername: form.father_name.data,
# add more fields
}
sqlsession.add(user_details)
return redirect(url_for('page_newuser'))
return render_template('newuser.html', form=form)
Once you have form then you can easily edit your content and directly save it to database
#app.route('/control/edituser/<int:id>',method=['post','get'])
def edit(id):
qry=sqlsession.query(Enduser).filter(Enduser.id==id).first()
form = UserForm(request.form, **qry)
if form.validate_on_submit():
form.populate_obj(qry)
sqlsession.update(qry)
sqlsession.commit()
return redirect(url_for('page_newuser'))
return render_template('newuser.html', form=form)

Flask get and edit values

I've got a site where I display specific values of a stock in a table and then should be able to change those values again when clicking on a button, that opens a modal with a form inside.
Now this is my first flask app and I’ve got a problem in overwriting my “original” data with the new Data I’m getting from my form. I don't really know how I can do that. My code looks like this:
views.py
#app.route("/stock-editor", methods=['GET', 'POST'])
def stock_editor():
index = Index(initial_date=app.config['INCEPTION_DATE'], initial_value=10000)
end_date = datetime.today()
start_date = app.config['INCEPTION_DATE']
empty_stocks = dict()
for symbol, shares in index.share_distribution.items(): # Here I get every empty stock and put inside a dict so that I can show it on my page
stock_value = StockValue.query.filter(StockValue.value_eur == 0.000000, StockValue.identifier == symbol, StockValue.date <= end_date, StockValue.date >= start_date).all()
if stock_value:
empty_stocks[symbol] = stock_value
if request.method == 'POST': # this is where I am failing, more info below
result = request.form
new_stock_value = request.values.get('new-stock-value')
new_source_value = request.values.get('new-source-value')
return render_template('stock-editor.html', result=result, empty_stocks=empty_stocks, start_date=start_date, end_date=end_date, new_stock_value=new_stock_value, new_source_value=new_source_value)
else:
return render_template('stock-editor.html', empty_stocks=empty_stocks, start_date=start_date, end_date=end_date)
The html:
<table class="table">
<tbody>
{% for symbol, stock_values in empty_stocks.items() %}
<tr class="table-active">
<th>Aktie</th>
<th>Datum</th>
<th>Wert</th>
<th colspan="2">Quelle</th>
</tr>
{% for value in stock_values %}
<tr>
<th>{{ symbol }}</th>
<td>{{ value.date.strftime('%d.%m.%Y')}}</td>
<td>{{ '%d' % value.value_eur }}</td>
<td>{{ value.source }}</td>
<td>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modal-{{ value.id }}">Bearbeiten <i class="fas fa-pencil-alt"></i></button>
<!-- The Modal -->
<div class="modal fade" id="modal-{{ value.id }}">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Aktie bearbeiten</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<form method="POST">
<label for="new-stock-value" class="col-form-label">Neuer Wert:</label>
<input type="number" name="new-stock-value" class="form-control" id="new-stock-value" placeholder="{{ '%d' % value.value_eur }}">
<label for="new-source-value" class="col-form-label">Quelle:</label>
<input type="text" name="new-source-value" class="form-control" id="new-source-value" placeholder="{{ value.source }}">
<!-- Modal footer -->
<div class="modal-footer">
<button type="submit" class="btn btn-success">Ändern</button>
<button type="button" class="btn btn-danger" data-dismiss="modal">Abbrechen</button>
</div>
</form>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
So in the if request.method == 'POST' I am getting my new values (new_stock_value and new_source_value) but I’m a little lost in HOW to actually set them as the new value of the stock where I am setting those new values?
Add a hidden field like below to the modal form,
<input type='hidden' name='id' value='{{ value.id }}'>
The above code snippet allows you to send the id of the current stock which is being edited. And in the route you can grab this id by,
id = request.values.get('id')
Using this id, update the empty_stocks dictionary with the new value of stock.
for symbol, stock_values in empty_stocks:
for value in stock_values:
if value.id == id:
value.value_eur = request.values.get('new-stock-value')
value.source = request.values.get('new-source-value')
break
I hope this helped you.

How to Add Extra Tab Using Template Language Twig In OpenCart 3.x

I want an extra description tag termed "Overview" for the product page under the nav nav-tabs class.
This is the complete Twig template code:
<ul class="nav nav-tabs">
<li class="active">{{ tab_description }}</li>
{% if attribute_groups %}
<li>{{ tab_attribute }}</li>
{% endif %}
{% if review_status %}
<li>{{ tab_review }}</li>
{% endif %}
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-description">{{ description }}</div>
{% if attribute_groups %}
<div class="tab-pane" id="tab-specification">
<table class="table table-bordered">
{% for attribute_group in attribute_groups %}
<thead>
<tr>
<td colspan="2"><strong>{{ attribute_group.name }}</strong></td>
</tr>
</thead>
<tbody>
{% for attribute in attribute_group.attribute %}
<tr>
<td>{{ attribute.name }}</td>
<td>{{ attribute.text }}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
</div>
{% endif %}
{% if review_status %}
<div class="tab-pane" id="tab-review">
<form class="form-horizontal" id="form-review">
<div id="review"></div>
<h2>{{ text_write }}</h2>
{% if review_guest %}
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label" for="input-name">{{ entry_name }}</label>
<input type="text" name="name" value="{{ customer_name }}" id="input-name" class="form-control" />
</div>
</div>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label" for="input-review">{{ entry_review }}</label>
<textarea name="text" rows="5" id="input-review" class="form-control"></textarea>
<div class="help-block">{{ text_note }}</div>
</div>
</div>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label">{{ entry_rating }}</label>
{{ entry_bad }}
<input type="radio" name="rating" value="1" />
<input type="radio" name="rating" value="2" />
<input type="radio" name="rating" value="3" />
<input type="radio" name="rating" value="4" />
<input type="radio" name="rating" value="5" />
{{ entry_good }}</div>
</div>
{{ captcha }}
<div class="buttons clearfix">
<div class="pull-right">
<button type="button" id="button-review" data-loading-text="{{ text_loading }}" class="btn btn-primary">{{ button_continue }}</button>
</div>
</div>
{% else %}
{{ text_login }}
{% endif %}
</form>
</div>
{% endif %}</div>
</div>
With this code, the page looks like this:
I want one more tab there saying OVERVIEW with different content.
Can anyone help me out here with this?
P.S: I did read this: how to add extra tab without any extension in product page in opencart
But, I'm not sure where to find this piece of code (I've tried looking product TPL files as well).
You Should try this its will add new tab name Overview
<ul class="nav nav-tabs">
<li class="active">{{ tab_description }}</li>
{% if attribute_groups %}
<li>{{ tab_attribute }}</li>
{% endif %}
{% if review_status %}
<li>{{ tab_review }}</li>
{% endif %}
<li>Overview</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-description">{{ description }}</div>
{% if attribute_groups %}
<div class="tab-pane" id="tab-specification">
<table class="table table-bordered">
{% for attribute_group in attribute_groups %}
<thead>
<tr>
<td colspan="2"><strong>{{ attribute_group.name }}</strong></td>
</tr>
</thead>
<tbody>
{% for attribute in attribute_group.attribute %}
<tr>
<td>{{ attribute.name }}</td>
<td>{{ attribute.text }}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
</div>
{% endif %}
{% if review_status %}
<div class="tab-pane" id="tab-review">
<form class="form-horizontal" id="form-review">
<div id="review"></div>
<h2>{{ text_write }}</h2>
{% if review_guest %}
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label" for="input-name">{{ entry_name }}</label>
<input type="text" name="name" value="{{ customer_name }}" id="input-name" class="form-control" />
</div>
</div>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label" for="input-review">{{ entry_review }}</label>
<textarea name="text" rows="5" id="input-review" class="form-control"></textarea>
<div class="help-block">{{ text_note }}</div>
</div>
</div>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label">{{ entry_rating }}</label>
{{ entry_bad }}
<input type="radio" name="rating" value="1" />
<input type="radio" name="rating" value="2" />
<input type="radio" name="rating" value="3" />
<input type="radio" name="rating" value="4" />
<input type="radio" name="rating" value="5" />
{{ entry_good }}</div>
</div>
{{ captcha }}
<div class="buttons clearfix">
<div class="pull-right">
<button type="button" id="button-review" data-loading-text="{{ text_loading }}" class="btn btn-primary">{{ button_continue }}</button>
</div>
</div>
{% else %}
{{ text_login }}
{% endif %}
</form>
</div>
{% endif %}
<div class="tab-pane" id="tab-overview">
<h1>Overview</h1>
<!-- Your HTML and twig code here-->
</div>
</div>
Output Image
You have just add two things
in ul tag add this li
<li>My Tab</li>
and add one div for tab-content
<div class="tab-pane" id="tab-overview">
<h1>My Tab Content</h1>
<!-- Your HTML and twig code here-->
</div>

Resources