I want checkboxes on my website. If these checkboxes are selected, an output should be output. If the checkboxes are not selected, nothing should happen.
I almost made it. But I don't know how to program that if the checkbox is not selected, nothing happens
Here is my try in my Python (flask):
#app.route("/checkbox", methods = ['GET','POST'])
def checkbox_value():
if request.method == 'POST':
if request.form.get("checkbox1"):
checkbox_data_1 = some_data
checkbox_title_1 = some_other_data
else:
#nothing should happen.
if request.form.get("checkbox2"):
checkbox_data_2 = some_data
checkbox_title_2 = some_other_data
else:
#nothing should happen.
return render_template('index.html', checkbox_data_1= checkbox_data_1, checkbox_title_1= checkbox_title_1, checkbox_data_2= checkbox_data_2, checkbox_title_2= checkbox_title_2 )
If I don't select a checkbox I get this error message "UnboundLocalError: local variable 'checkbox_data_1' referenced before assignment"
That error means that you are referencing a variable before it is declared.
In the case where checkbox 1 is not selected, you will be referencing checkbox_data_1 and checkbox_title_1 in the return statement when they have not been declared since the code does not enter the first if block. Same goes for checkbox 2.
To resolve this, simply initialize them with some default value. I went ahead and declared it as None but go ahead and change it to what works for you.
#app.route("/checkbox", methods = ['GET','POST'])
def checkbox_value():
checkbox_data_1 = None
checkbox_title_1 = None
checkbox_data_2 = None
checkbox_title_2 = None
if request.method == 'POST':
if request.form.get("checkbox1"):
checkbox_data_1 = some_data
checkbox_title_1 = some_other_data
if request.form.get("checkbox2"):
checkbox_data_2 = some_data
checkbox_title_2 = some_other_data
return render_template('index.html', checkbox_data_1= checkbox_data_1, checkbox_title_1= checkbox_title_1, checkbox_data_2= checkbox_data_2, checkbox_title_2= checkbox_title_2 )
Also, there is no need for an else block if you're going to leave it empty
Related
In my routes.py I set a variable to the converted dictionary generated from SQLAlchemy tuples right after the form validation statement.
When typing from routes import *
dict(Book.query.with_entities(Book.username, Book.choice).all()) in console i get the correct dictionary as wanted {'user1': 'choice1', 'user2': 'choice2'}
If I type the name of the variable dict_of_users assiged to this dictionary I get: NameError: name 'dict_of_users' is not defined
Why it does not recognise that variable since it is in the code?
The logic behind I want to achieve:
If the user select one choice from available in the list, that user and its choice are added as key and value in the dictionary, otherwise the dictionary is empty.
My routes.py:
#app.route("/booking", methods=['POST', 'GET'])
def booking():
session.permanent = True
app.permanent_session_lifetime = timedelta(seconds=5)
form = BookingForm()
if form.validate_on_submit():
book = Book(username=current_user.username, choice=form.book.data)
db.session.add(book)
db.session.commit()
flash('Your choice is registered', 'success')
dict_of_users = dict(Book.query.with_entities(Book.username, Book.choice).all())
return render_template('booking.html', title='Booking', form=form, dict_of_users=dict_of_users)
If it's only inside of the function, you can't access it outside of the function. Since the variable is only defined in the function, you get the NameError message. A fix is to define the variable in the global scope.
EDIT:
As a response to your comment:
if you want to access the dict_of_users variable, declare it outside of the function. Then the variable will contain the value of it's latest use in the global scope, and thus accesible outside of the function.
Something like this should do the trick:
dict_of_users = None
#app.route("/booking", methods=['POST', 'GET'])
def booking():
session.permanent = True
app.permanent_session_lifetime = timedelta(seconds=5)
form = BookingForm()
if form.validate_on_submit():
book = Book(username=current_user.username, choice=form.book.data)
db.session.add(book)
db.session.commit()
flash('Your choice is registered', 'success')
dict_of_users = dict(Book.query.with_entities(Book.username, Book.choice).all())
return render_template('booking.html', title='Booking', form=form, dict_of_users=dict_of_users)
Hi am new to both python and Odoo development, I used the web interface for customization before. I was trying to create a class to
add a field to sale.subscription Model
subscription_tier = fields.Char(string='Subscription Tier',readonly=True)
which is working but the second part is not working
2. loop through subscription line to see if the customer has silver or gold subscription
then set it to the field subscription_tier
class subscription_tire_set(models.Model):
_inherit = 'sale.subscription'
subscription_tier = fields.Char(string='Subscription Tier',readonly=True)
#api.depends('recurring_invoice_line_ids.product_id')
def _compute_release_to_pay(self):
for n_subscription in self:
result = None
for n_subscription_line in n_subscription.recurring_invoice_line_ids:
if any(n_subscription_line.product_id) == 'gold':
result = 'gold'
break
else:
result = 'not'
subscription_tier = result
I probably am doing something horribly wrong
also a getting this massge when trying to open any customer in subscription
Something went wrong!
sale.subscription(10,).subscription_tier
Thank u for the help in advance.
What worked for me:
result = None
for n_subscription_line in n_subscription.recurring_invoice_line_ids:
if n_subscription_line.product_id.name == 'gold'
result = 'gold'
# break
else:
result
n_subscription.subscription_tier = result
It is not working because in the last line you are declaring a variable named subscription_tier and set its value to result, you should assign the result to subscription_tier field of the the n_subscription record:
#api.depends('recurring_invoice_line_ids.product_id')
def _compute_release_to_pay(self):
for n_subscription in self:
# Your code
n_subscription.subscription_tier = result
Edit:
any will return True or False and your expression any(n_subscription_line.product_id) == 'gold' will always be evaluated to False
I'm making a web application, where user action can affect some bar graphs (seen in the gif below). Sometimes, changes aren't saved. When I reload the page, the changed bar graphs are shown (indicating that the user's action's were saved). When I reload the page again, sometimes the updated bar graphs and corresponding list are shown. Other times, they are not.
Here's the code for the view:
#app.route('/')
def home():
'''homepage for application'''
# redirect users who go to home page but aren't logged in
if not current_user.is_authenticated:
return redirect(url_for("landing"))
# reset the session
db.session.flush()
# get most recent entered weight
try:
last_weight = WeightEntry.query.filter_by(user_id = current_user.user_id).order_by(WeightEntry.date)[-1]
except IndexError:
return error("No weight recorded. Please contact support.")
return render_template("home.html",
today= Today(current_user.user_id),
foods = [food for food in FoodEntry.query.filter_by(user_id=current_user.user_id).all() if food.is_today() == True],
options = sorted(Food.query.filter(Food.user_id==current_user.user_id).all(), key=lambda x: x.name),
last_weight = last_weight)
I added the db.session.flush() in an attempt to solve the problem, but that didn't work.
The changes (logged foods) are stored here:
#app.route("/log_food", methods=["POST", "GET"])
#login_required
def log_food():
# add foods given by the user
if request.method == "POST":
for food in request.form.getlist("logged_food"):
try:
added_food = Food.query.filter_by(user_id=current_user.user_id, name=food).first()
x = FoodEntry(
food_id = added_food.food_id,
user_id = current_user.user_id)
db.session.add(x)
db.session.commit()
except:
return error("Unable to log food.")
return redirect(url_for("home"))
I'd appreciate any help I can get.
Thanks!
I fixed it by adding db.session.commit() to the page functions.
For example, for the homepage: I did:
#app.route('/')
def home():
'''homepage for application'''
db.session.commit()
...
I can not understand this behavior at all. I asked a question yesterday or the day before thinking it was something with bottle.py, but after trying all kinds of possible solutions, even converting my app over to flask, I have pinpointed the behavior to a single, very simple, class, but I have NO idea why this is happening. It's confusing the hell out of me, but I would really like to understand this if anyone can please shed some light on it.
Ok, so first I have a class called Page which simplifies setting up templates a bit, this is the offending class:
class Page:
"""The page object constructs the webpage and holds associated variables and templates"""
def __init__(self, template=None, name = '', title='',template_vars={}, stylesheets=[], javascript=[]):
# Accepts template with or without .html extension, but must be added for lookup
self.stylesheet_dir = '/css'
self.javascript_dir = '/js'
self.template = template
self.template_vars = {}
self.name = name
self.title = title
self.stylesheets = stylesheets
self.javascript = javascript
self.template_vars['debug'] = _Config.debug
self.template_vars['title'] = self.title
self.template_vars['stylesheets'] = self.stylesheets
self.template_vars['javascript'] = self.javascript
def render(self):
"""Should be called after the page has been constructed to render the template"""
if not self.template.endswith(_Config.template_extension):
self.template += '.' + _Config.template_extension
if not self.title:
if self.name:
self.title = _Config.website + _Config.title_delimiter + self.name
else:
# If title not given use template name
self.title = _Config.website + _Config.title_delimiter + self.template.rstrip('.html')
try:
template = env.get_template(self.template)
except AttributeError:
raise (AttributeError, 'template not set')
rendered_page = template.render(self.template_vars)
return rendered_page
def add_stylesheet(self, name, directory=None):
# Sanitize name
if not name.endswith('.css'):
name += '.css'
if name.startswith('/'):
name = name.lstrip('/')
if not directory:
directory = self.stylesheet_dir
self.template_vars['stylesheets'].append(directory + '/' + name)
def add_javascript(self, name, directory=None):
# Sanitize name
if not name.endswith('.js'):
name += '.js'
if name.startswith('/'):
name = name.lstrip('/')
if not directory:
directory = self.javascript_dir
self.template_vars['javascript'].append(directory + '/' + name)
And here is an example of a route that the problem is exhibited:
#route('/create_account', method=['GET','POST'])
def create_account():
dbsession = db.Session()
page = Page('create account')
page.add_javascript('create_account.js')
if request.method == 'GET':
page.template = 'create_account'
page.template_vars['status'] = None
document = page.render()
dbsession.close()
return document
elif request.method == 'POST':
# Omitted
The problem lies with the method Page.add_javascript(). The next time I go to the /create_account page it is not creating a new Page object and instead reusing the old one. I know this because if I go to the page twice I will have two entires for the create_account.js in my returned html document(the template simply runs a for loop and creates a tag for any js files passed in that list). If I go 3 times it'll be listed 3 times, 40, 40 and so on. Now however if I simply change it to use the initializer and not the add_javascript method the problem goes away.
#route('/create_account', method=['GET','POST'])
def create_account():
dbsession = db.Session()
page = Page('create account', javascript=['create_account.js'])
if request.method == 'GET':
page.template = 'create_account'
page.template_vars['status'] = None
document = page.render()
dbsession.close()
return document
elif request.method == 'POST':
However I suspect something is still wrong and just for my own sanity I need to understand what the hell is going on here. What is possibly happeneing behind the scenes where the add_javascript method would be called twice on the same page object? The method is called immediately after creating a new instance of the page object, where is it possibly getting the old contents of template_vars from?
The problem is that you use mutable defaults for your Page.__init__ function. See http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments.
So you do get a new Page instance on each request, but the lists/dictionaries that hold your javascript etc are re-used.
Replace list/dict default argument values with None, check for None in __init__.
I am trying to do the following:
class PurchaseCreate(CreateView):
template_name = "generic_create.html"
model = Purchase
form_class = PurchaseForm
try:
latest_tag = Purchase.objects.latest('tag').tag
print(latest_tag)
next_tag = latest_tag + 1
except:
next_tag = 1
initial = {'tag': next_tag}
The "tag" field should start with a value that is + 1 of the previous value that has been entered. When I test it out in the Django API, it works fine. However, when called from the view, it works correctly the first time, but seems to get "stuck" returning that first value, even when new objects are created which should update the value.
In fact, the try/except portion is never executed after the first page load, as the print order never shows up in the terminal, even with a hard browser refresh. How do I set this view to send an updated result every time the page is loaded?
As suggested, I moved the logic into the get_initial() method like so:
def get_initial(self):
super(PurchaseCreate, self).get_initial()
try:
latest_tag = Purchase.objects.latest('tag').tag
print(latest_tag)
next_tag = latest_tag + 1
except:
next_tag = 1
initial = {'tag': next_tag}
return initial