Turbogears2 session management - python

In theory i did what i'm supposed to do in order to store some data in session variables but my controllers can't reach them. Here's the code:
#expose('')
#require(predicates.not_anonymous())
def savecustomer(self, customer=None, **kw):
if customer is None:
flash(_('Select a customer!'), 'error')
redirect('/')
customer = DBSession.query(Customer).filter_by(customer_id=customer).first()
session.delete()
session['customer'] = True
session['customer_id'] = customer.customer_id
session['customer_name'] = customer.customer_name
...
session.save()
and here is my view code:
{% if request.identity %}
{% if session['customer'] %}
<div class="customer"><i>{{ session['customer_name'] }}
{% if session['customer_type'] %} {{ session['customer_type'] }} {% endif %}
</i></div>
{% else %}
<div class="nocustomer">No customer selected</div>
{% endif %}
{% endif %}
and here's my "debugging":
for i in session.iterkeys():
print i
for i in session.itervalues():
print i
customer
customer_id
customer_name
True
3
Ciccio Pasticcio S.p.a.
and if i run the same code in another controller it gives me this:
_id
832f62d3bc5140c4a9f3ba36bc3e876a
What am i doing wrong? (this used to work until i "fixed" something else :) )

I solved the error by removing
session.delete()

Related

Why do I get QuerySet object has no attribute user

I am working on a website using Django, where users can send friend
request to another user and I came up with an error on my code. Queryset object has no attribute user. According to my attached images, when I click on the follow button of the first user, all buttons changes text to 'cancel', but when I click on the button of the second user it does not change the text. I want when button clicked button text should be able to change for each users.
def home(request):
p = Profile.objects.exclude(user=request.user)
u = p.user
sent_request = FriendRequest.objects.filter(from_user=p.user)
button_status = 'none'
if p not in request.user.profile.friends.all()
button_status = 'not_friend'
if len(FriendRequest.objects.filter(from_uset=request.user).filter(to_user=p.user)) == 1:
button_status='add_request'
if len(FriendRequest.objects.filter(from_user=p.user).filter(to_user=request.user)) == 1:
button_status='cancel_request'
context = {'u':u, 'p':p, 'sent_request',:sent_request, 'button_status':button_status,}
return render(request, 'home.html', context)
{% for profile in p %}
{{ profile }}
{% if not request.user in u %}
{% if button_status == 'not_friend' %}
href = add url here
{% elif button_staus == 'cancel_request' %}
href = cancel request url here
{% endif %}
{% endif %}
{% endfor %}
#This only execute once on template, instead of twice (duplicate). How do I make this display twice in template?
{% for data in profile_and_button_status %}
{% data.0.user.username %}
#All codes here
{% endfor %}
{% if forloop.counter == 1 %}
{% for data in profile_and_button_status %}
#All codes here
{% data.0.user.username %}
{% endfor %}
{% endif %}
Because .exclude() will give you an queryset. So, you have to first iterate that queryset and get required user from there.
Because queryset it mean the list.
I think you have to pass zip of profiles list p and button status list button_status of a particular users as below...
def home(request):
p = Profile.objects.exclude(user=request.user)
all_profile_users = []
button_status_list = []
for user_obj in p:
u = user_obj.user
all_profile_users.append(u)
sent_request = FriendRequest.objects.filter(from_user=u)
friends = Profile.objects.filter(user=request.user, friends__id=user_obj.id).exist()
button_status = 'none'
if not friends
button_status = 'not_friend'
if len(FriendRequest.objects.filter(from_uset=request.user).filter(to_user=p.user)) == 1:
button_status='add_request'
if len(FriendRequest.objects.filter(from_user=p.user).filter(to_user=request.user)) == 1:
button_status='accept_request'
button_status_list.append(button_status)
context = {'u':all_profile_users, 'profile_and_button_status': zip(p, button_status_list), 'sent_request':sent_request}
Then, iterate profile_and_button_status in template as below...
{% for data in profile_and_button_status %}
<div class="row mb-2">
... YOUR DESIGN CODE ...
{{ data.0.user.username }}
{% if not request.user in u %}
{% if data.1 == 'not_friend' %}
... YOUR DESIGN CODE ...
{% elif data.1 == 'follow_request_sent' %}
... YOUR DESIGN CODE ...
And so on for other conditions.
For remove friend :
def remove_friend(request, id):
... YOUR LOGIC ...
frequest = FriendRequest.objects.filter(from_user=from_user, to_user=request.user).first()
if frequest is None:
frequest = FriendRequest.objects.filter(from_user=request.user, to_user=from_user).first()
user1 = frequest.to_user
user2 = from_user
... YOUR LOGIC ...

How to iterate through multidimensional list/dict in a template

I try to rebuild this example:
https://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/
I have a model "Product" and a model "Order". Order has a foreignkey to "product". So for 1 Product I have N Orders
In my template I have to display a lot of information so I would like to avoid to do "for order in Product.order_set.all()" in my template
In my template, if I write :
{{ object_list.1.related_items }}
everything is fine and I get what I want
but if I write:
{% for i in object_list %}
{{ object_list.i.related_items }}
{% endfor %}
I don't get a result.
Can somebody tell me how I solve this problem?
My object_list is nearly the same as in the above example:
products = Product.objects.all()
i = 0
qs = Product.objects.all()
obj_dict = dict([(obj.id, obj) for obj in qs])
objects = Order.objects.filter(producttyp__in=qs)
relation_dict = {}
for obj in objects:
relation_dict.setdefault(obj.producttyp_id, []).append(obj)
for id, related_items in relation_dict.items():
obj_dict[id].related_items = related_items
def get(self,request,*args,**kwargs):
context = {'object_list':self.obj_dict}
return render(request,self.template_name,context)
the only change i did is from
obj_dict[id]._related_items to obj_dict[id].related_items because of the not allowed underscore?!
How do I print the list in my template like:
- Product A
- Order 1
- Order 2
- Order 5
- Product B
- Order 3
- Order 6
best regards
That is logical, since here Django interprets i not as the variable, but as the an identifier, so it aims to access object_list.i, or object_list['i'], not object_list.1 for example.
You however do not need i here, you can just access the related_items of the object, like:
{% for object in object_list %}
{{ object.related_items }}
{% endfor %}
If related_items is, as the name suggests, a collection as well, we can iterate over these items as well:
{% for object in object_list %}
{% for subitem in object.related_items %}
{{ subitem }}
{% endfor %}
{% endfor %}
for a dictionary, we can access the .values, like:
{% for object in object_dict.values %}
{{ object.related_items }}
{% endfor %}
EDIT: as for the specific case of the listview. You can use .prefetch_related to fetch all the relations with one extra query:
class MyListView(ListView):
queryset = Product.objects.prefetch_related('order_set')
template = 'my_template.html'
In the template you can then render this like:
<ul>
{% for product in object_list %}
<li>{{ product }}</li>
<ul>
{% for order in product.order_set %}
<li>{{ order }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>

Counter increment in template outside of for loop

I need to do a counter increment within a loop. I had a look at django for.counter, but unfortunately, my increments dont exactly occur within each iteration of the loop. So is there any way at all that I can implement increment of a variable within django template, without going to great pains to implement a new object in my code to do this without such an increment?
In the following code, I am writing the lines {{ count = 0 }}, {{ count += 1 }} just for illustration purpose. I know it wont work. The following is a very simplified form of my template:
<div class="jumbotron slotgroup slotavailable mb-1 mt-5" id="jumbo_week_avail">
<div class="slot-header" role="alert">
Headertext
</div>
{% if weeklyslotsav %}
{% for day,daynum in weekzip %}
{{ count = 0 }}
{% if daynum in weeklyslotsav.day %}
{% for weekslotav in weeklyslotsav %}
{% if weekslotav.day == daynum %}
<div class="row row_week_avail{{ weekslotav.day }}" id="row_week_avail{{ weekslotav.day }}_{{ count }}">
</div>
{{ count += 1 }}
{% endif}
{% endfor %}
{% else %}
<div class="row row_week_avail{{ daynum }}" id="row_week_avail{{ daynum }}_0">
</div>
{% endif %}
{% endfor %}
{% else %}
{% for weekday, weeknum in weekzip %}
<div class="row row_week_avail{{ weeknum }}" id="row_week_avail{{ weeknum }}_0">
</div>
{% endfor %}
{% endif %}
</div>
The following is a segment from my views:
def edit_doctorslots(request, cliniclabel, doctor_id):
doctor_id=int(doctor_id)
doc = get_object_or_404(doctor, docid=doctor_id)
cl = Clinic.objects.get(label=cliniclabel)
print("Clinic name", cl.name)
regularslotsav = ''
try:
regularslotsav = Timeslots.objects.filter(clinic =cl, doctor =doc, available =True)
except:
pass
regularslotsbr = ''
try:
regularslotsbr = Timeslots.objects.filter(clinic =cl, doctor =doc, available =False)
except:
pass
weekavzip = ''
try:
weeklyslotsav = Weekdays.objects.filter(clinic =cl, doctor =doc, available =True)
weekav = range(0, len(weeklyslotsav))
weekavzip = list(zip(weeklyslotsav, weekav))
except:
pass
weeklyslotsbr = ''
try:
weeklyslotsbr = Weekdays.objects.filter(clinic =cl, doctor =doc, available =False)
except:
pass
formslot = SlotForm()
formspecialdays = SpecialdaysForm()
formweekdays = WeekdaysForm()
weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
weekdaynum = [0,1,2,3,4,5,6]
weekzip = list(zip(weekdays, weekdaynum))
newweekzip = weekzip
return render(request, 'clinic/editslots0.html', {'rnd_num': randomnumber(), 'clinic': cl, 'doctor': doc, 'formslot': formslot, 'formspecialdays': formspecialdays, 'formweekdays': formweekdays, 'weekzip': weekzip, 'newweekzip': newweekzip, 'regav': regularslotsav, 'regbr': regularslotsbr, 'weekav': weekavzip, 'weekbr': weeklyslotsbr, 'weeklyslotsav': weeklyslotsav })
I've seen many similiar questions on SO. However in all of them I've seen people introducing for.counter. But this is not suitable for my purpose.
You can use with tag to set variables in template as -
{% with count=0 %}
{{ count}}
...do other stuffs
{% endwith %}
and for maths you could use django math filters like
{{ count|add:"1" }}
You can code you with use of both.
For more about setting variable in django template - How to set a value of a variable inside a template code?
and for using math in django - How to do math in a Django template?
Hope this helps you.

How can i access a jinja2 variable outside the for loop?

im trying to use a for loop to add up some numbers for each day
and i would like to access the variable outside the for loop im not sure how to go about this I am using the flask framework with python and just come from weppy where this was not a problem is there a way to make it work the same way in flask?
here is some simple code
{% set newtotal = 0 %}
{% for item in daily: %}
{% set newtotal = newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{ newtotal }}</span>
</div>
the numbers collected by item[10] are dollar values
if i place the {{ newtotal }} before the endfor it shows every value as its being added up this is not what I want
EDIT:
if it helps daily is a list of 8 tuples
Please keep in mind that it is not possible to set variables inside a block or loop and have them show up outside of it.
As of version 2.10 this can be handled using namespace objects which allow propagating of changes across scopes.
Here is your code using namespace:
{% set ns = namespace (newtotal = 0) %}
{% for item in daily: %}
{% set ns.newtotal = ns.newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{ ns.newtotal }}</span>
</div>
One solution (probably the "simplest") would be to change your Python script to pass in a variable named newtotal that would simply be the length of the daily list!
Alternatively, you could use the length filter:
{{things|length}}
In which case your code could look something like this:
{% set newtotal = 0 %}
{% for item in daily: %}
{% set newtotal = newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{daily|length}}</span>
</div>
Hope it helps!
Additional Sources:
jinja2: get lengths of list
How do I access Jinja2 for loop variables outside the loop?
EDIT
Sorry, I misread the question!
You can use the sum filter instead ({{ list | sum() }}).
So your code could look like:
{% set newtotal = 0 %}
{% for item in daily: %}
{% set newtotal = newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{ daily | sum() }}</span>
</div>
New sources:
Documentation
Sum elements of the list in Jinja 2
Use the namespace object.
https://jinja.palletsprojects.com/en/master/templates/#assignments
Here’s a working example from my config.
{% set i= namespace(fxp0_ip=0) %}
{% set i= namespace(mgmt_ip = 0) %}
{% set i= namespace(loopback_ip = 0) %}
{% set i= namespace(lan_ip = 0) %}
{% set i= namespace(wan_ip = 0) %}
{% for interface in device_vars.interfaces %}
{% elif interface.name == "ge-0/0/0" %}
{% set i.mgmt_ip = interface.ip_addr %}
{% elif interface.name == "lo0" %}
{% set i.loopback_ip = interface.ip_addr %}
{% elif interface.name == "ge-0/0/2" %}
{% set i.lan_ip = interface.ip_addr %}
{% elif interface.name == "ge-0/0/1" %}
{% set i.wan_ip = interface.ip_addr %}
{% endif %}
{% endfor %}
{{i.mgmt_ip}}
{{i.wan_ip}}

WTforms IntegerField in fieldlist never validates using manual iteration

I have an InterField, that validates if a number is between the values 0 and 99. For some reason it never validates.
I have a feeling it is related to the FieldList and ther way I iterate over it in the template, but can't seem to get it working.
The form:
class dpiaImpactAnalysisForm(Form):
severity_score = IntegerField("Severity Score"),
validators=[NumberRange(min=0, max=99, message="Please provide a valid number")]))
identifiability_score = IntegerField("Identifiability Score"),
validators=[NumberRange(min=0, max=99, message="Please provide a valid number")]))
class dpiaThreatAnalysisForm(Form):
impact = FieldList(FormField(dpiaImpactAnalysisForm), min_entries=1)
In views I append the entries dynamically as required:
#app.route('/dpia/analysis/<project_id>', methods=["GET", "POST"])
def analysis(project_id):
form = dpiaThreatAnalysisForm()
prim = Assets.query.filter_by(selected=True, primary=True).all()
primary_assets = list(map(vars, prim))
ev = Events.query.all()
events = list(map(vars, ev))
# add fields to the form...
for z in range(len(prim) * len(ev)):
form.impact.append_entry()
supp = Assets.query.filter_by(selected=True, primary=False).all()
supporting_assets = list(map(vars, supp))
ths = Threats.query.all()
threats = list(map(vars, ths))
# add fields to the form
for z in range(len(ths) * len(supp)):
form.likelihood.append_entry()
if form.is_submitted():
print "submitted"
if form.validate():
print "valid"
print form.errors
if form.validate_on_submit():
# This is never printed:
app.logger.info("success!!")
pprint(form.likelihood)
return redirect(url_for(next_step, project_id=project_id))
return render_template('analysis.html', form=form, threats=threats, supporting_assets=supporting_assets, primary_assets=primary_assets, events=events)
In the template I iterate over a list primary_assets in a list events, and add the fields per iteration:
{% for val in events %}
{% if not counter or loop.index0 == 0 %}
{% set counter = [] %} <!-- loop hack !-->
{% endif %}
<strong>Event: {{ val.name }}</strong><br />
Jeopardizes: {{ val.jeopardizes }}<br />
{% for pa in primary_assets %}
<strong>{{ pa['name'] }}</strong><br />
{{ form.impact[counter|length].identifiability_score(placeholder='') }} <br />
{{ form.impact[counter|length].severity_score(placeholder='') }}
{{ form.impact[counter|length].hidden_tag() }}
{% if counter.append('1') %}{% endif %}
{% endfor %}
{% endfor %}
The hidden_tag() doesn't work either. Normally I iterate of the forms with with something like
{% for impact in form.impact %}
{{ impact.form.hidden_tag() }}
# do cbg
{% endfor %}
and that works, that's why I believe it's my manual looping that spoils it...
EDIT 2 march, 17:26
After some testing, I found that using
severity_score = IntegerField("Severity Score", validators=[Optional(), NumberRange(
min=0, max=9999999999, message="Please provide a valid number")])
works (if I set min=50 I get an error when inserting a number below 50), however, the CSRF is still not getting passed.
{{ form.impact[counter|length].hidden_tag() }} or
{{ form.impact[counter|length].form.hidden_tag() }} both don't work :(
I'm getting: {'impact': [{'csrf_token': ['CSRF token missing']}, {'csrf_token': ['CSRF token missing']}]}
EDIT 18:22
It seems that this: Form validation fails due missing CSRF is the solution. Investigating...
This: Form validation fails due missing CSRF is the solution.
In previous versions this wasn't needed, and after an installation of a new extension pip updated flask-wtf as well...

Categories