Flask forms, filter using drop down - flask-sqlalchemy

Newbie Attempting to filter returned items based on cascading dropdowns.
Get the following error:
NotImplementedError: Operator 'getitem' is not supported on this expression
Code Below
`class Asset(db.Model):
"""
asset table
"""
__tablename_ = 'asset'
inv_id = db.Column(db.String(15), primary_key=True)
descript = db.Column(db.String(50))
station = db.Column(db.String(3))
inv_class = db.Column(db.String(10))
#admin.route('/assets', methods=['GET', 'POST'])
#login_required
def list_assets():
form = Form()
form.station.choices = [(Asset.station) for station in
Asset.query.filter_by(inv_class='HOSE').all()]
class Form(FlaskForm):
inv_class = SelectField('inv_class', choices = [])
station = SelectField('station', choices = [])
<body>
<form method="GET","POST">
{{ form.inv_class }}
{{ form.station }}
</form>
</body>
Fist dropdown should filter to inv_class, second by station, then return list of assets that include both.

Related

how to implement a section block in eLearning module - odoo 14

i was tryin to add a section block which allows me to block all the possible sections (except for the first) and then if all the slides in the section are complete, makes the next one available
I tried with the templates but it don't seem the way to approach this problem cause I cannot find any way to check the previous slides, I was trying to figure it out with javascript maybe but I'm not that good with JS
that's my actual progress:
<odoo>
<data>
<template id="section_lock" inherit_id='website_slides.course_slides_list_slide'>
<xpath expr="//div[#class='text-truncate mr-auto']" position="replace">
<div class="text-truncate mr-auto">
<a t-if="slide.is_preview or slide.previous_category_complete is False or channel.can_publish"
class="o_wslides_js_slides_list_slide_link" t-attf-href="/slides/slide/#{slug(slide)}">
<span t-field="slide.name"/>
</a>
<span t-else="">
<span t-esc="slide.name"/>
</span>
</div>
</xpath>
</template>
</data>
and then the model with the flag needed for the check
class Slide(models.Model):
_inherit = 'slide.slide'
previous_category_complete = fields.Boolean(default=True)
how do u suggest to do it? I think i'm way off th road with this
The relationship between an e-Course and its section is based on the same model (slide.slide) using these relational fields :
category_id = fields.Many2one('slide.slide', string="Section", compute="_compute_category_id", store=True)
slide_ids = fields.One2many('slide.slide', "category_id", string="Slides")
#api.depends('channel_id.slide_ids.is_category', 'channel_id.slide_ids.sequence')
def _compute_category_id(self):
self.category_id = False # initialize whatever the state
channel_slides = {}
for slide in self:
if slide.channel_id.id not in channel_slides:
channel_slides[slide.channel_id.id] = slide.channel_id.slide_ids
for cid, slides in channel_slides.items():
current_category = self.env['slide.slide']
slide_list = list(slides)
slide_list.sort(key=lambda s: (s.sequence, not s.is_category))
for slide in slide_list:
if slide.is_category:
current_category = slide
elif slide.category_id != current_category:
slide.category_id = current_category.id
To know wether a specific student has attended an e-course, there is an existing field in the model 'slide.slide.partner':
class SlidePartnerRelation(models.Model):
_name = 'slide.slide.partner'
slide_id = fields.Many2one('slide.slide', ondelete="cascade", index=True, required=True)
partner_id = fields.Many2one('res.partner', index=True, required=True, ondelete='cascade')
completed = fields.Boolean('Completed')
So you can check wether all the previous Slide Sections are completed for the current partner_id, inheriting the class WebsiteSlides located in website_slides/controllers/main.py > def channel(...)... :
from odoo.addons.website_slides.controllers.main import WebsiteSlides
class WebsiteSlidesCustom(WebsiteSlides):
#http.route()
def channel(self, channel, category=None, tag=None, page=1, slide_type=None, uncategorized=False, sorting=None, search=None, **kw):
res_super = super(WebsiteSlidesCustom, self).channel(channel, category=None, tag=None, page=1, slide_type=None, uncategorized=False, sorting=None, search=None, **kw)
values = res_super.qcontext
sections_completion = request.env['slide.slide.partner'].sudo().search([
('channel_id', '=', current_channel_id),
('is_category','=', True),
('partner_id', '=', request.env.user.partner_id.id)
])
dic_sections_completion={}
for sec in sections_completion.sorted('sequence'):
dic_sections_completion[sec.id] = sec.completed
values['sections_completion'] = dic_sections_completion
return request.render('website_slides.course_main', values)
in your module directory views, create a new xml file : course_main_custom.xml
<template id="course_main_custom" inherit_id="website_slides.course_main" name="Course Main" >
<xpath expr="//t[#t-set='category']" position="after">
...
</xpath>
</template>

using curly double brackets inside another curly double brackets in django template

I started studying Django few days back, while doing a project I came across a situation.
In the views.py, I'm passing
def chat_rooms(request):
context = dict()
context['title'] = 'Chat'
rooms = Chat_rooms.objects.filter(Q(user1 = request.user.id) | Q(user2 = request.user.id) )
context['rooms'] = rooms
for room in rooms:
rmssg = Chats.objects.filter(room_id = room.id)
lmssg = Chats.objects.latest('id')
context[str(room.id)] = lmssg
return render(request,'previlageGroup/chat_rooms.html',context)
In the Django template,chat_room.html
{% for room in rooms %}
<div class="card" style="width: 100%;">
<a href="{% url 'pgroup:chat.screen' room.id %}">
<div class="card-body">
<p class="card-text">
{{ {{room.id}}.message}}
</p>
</div>
</a>
</div>
{% endfor %}
In models.py
class Chat_rooms(models.Model):
user1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user1')
user2 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user2')
created_on = models.DateTimeField(auto_now_add=True)
class Chats(models.Model):
date = models.DateTimeField(auto_now_add=True)
has_viewed = models.BooleanField(default= False)
message = models.CharField(max_length = 200)
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sender')
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name='receiver')
room = models.ForeignKey(Chat_rooms, on_delete=models.CASCADE)
Django is giving me a error, that {{ {{room.id}}.message }} is not possible.
How can I do this? Is there any other way? Thanks in advance
At the end of the day, a django Model object is just like any other object in python, so you could easily do:
for room in rooms:
rmssg = Chats.objects.filter(room_id = room.id)
lmssg = Chats.objects.latest('id')
room.last_msg = lmssg
And access {{ room.last_msg }} in your template. This might cause errors if you ever happen to implement a last_msg field though.
Perhaps a more elegant solution would be implementing a related_name to your room field. If you change the last line of your views.py to:
room = models.ForeignKey(Chat_rooms, on_delete=models.CASCADE, related_name="chats")
You would be able to do things like:
room.chats.all() #get all messages from a chatroom
And, in your templates, you could do:
{{ room.chats.last }}
To get the last message in the chat.

How to insert data to a table using transient model(wizard) in odoo 10

I have a model named Vehicle and i have created a wizard od_add_new_vehicle.
In the xml view of wizard i have created an action.
How do i link the Vehicle model with the wizard so that i can save data permanantly
class Vehicle(models.Model):
_name = 'transport.vehicle'
name = fields.Char(string="Name", required=True)
description = fields.Text()
reg_date = fields.Date()
department = fields.Char()
available = fields.Boolean()
class od_add_new_vehicle(models.TransientModel):
_name = 'od.add.new.vehicle'
_description = 'Add new vehicle'
name = fields.Char('vehicle name')
description = fields.Text('Description')
reg_date = fields.Date('Reg date')
department = fields.Char('Department')
available = fields.Boolean('Available')
def _default_veh(self):
return self.env['transport.vehicle'].browse(self._context.get('active_ids'))
v_id = fields.Many2one('transport.vehicle', string="Vehicle ref", required=True, default=_default_veh)
#api.multi
def od_add_book(self):
self.v_id.name = self.name
self.v_id.description = self.description
self.v_id.reg_date = self.reg_date
self.v_id.department = self.department
self.v_id.available = self.available
self.v_id.member_id = self.member_id
return {}
Following is simple way to update/insert data from Wizard.
Add button on form view footer
Button type will be object to call python function in .py side
Use active_ids to update record-set.
For example:
<footer>
<button name="insert_data" string="Insert/Update data" type="object"
class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
.py side function
#api.multi
def insert_data(self):
for record in self.env['target.table.name'].browse(self._context.get('active_ids', [])):
#here you can access target table fields using *record* variable
record.field_name = wizard.field_name
return True

How to display items in a sorted order?

I have this in my template file:
{% get_latest_show as slideshow %}
{% for slide in slideshow.slide_set.all %}
<img src="{% thumbnail slide.image 1174x640 upscale %}" alt="{{slide.title}}" width="1174"/>
{% endfor %}
models.py
from django.db import models
import datetime
class Slide(models.Model):
title = models.CharField(max_length=50)
description = models.TextField(blank=True, null=True)
target_url = models.TextField(blank=True, null=True)
slideshow = models.ForeignKey('Slideshow')
image = models.ImageField(upload_to='slideshow', max_length=500, blank=True,null=True)
def __unicode__(self):
return self.title
class Slideshow(models.Model):
title = models.CharField(max_length=50)
pub_date = models.DateTimeField(auto_now=True)
published = models.BooleanField(default=False)
class Meta:
ordering = ['-title']
def __unicode__(self):
return self.title
slide_tags.py
from django import template
from django.core.cache import cache
from django.contrib.contenttypes.models import ContentType
from slides.models import Slide, Slideshow
register = template.Library()
class GetSlideshowNode(template.Node):
"""
Retrieves the latest published slideshow
"""
def __init__(self, varname):
self.varname = varname
def render(self, context):
try:
show = Slideshow.objects.filter(published=True)[0]
except:
show = []
context[self.varname] = show
return ''
def get_latest_show(parser, token):
"""
Retrieves the latest published slideshow
{% get_latest_show as show %}
"""
args = token.split_contents()
argc = len(args)
try:
assert (argc == 3 and args[1] == 'as')
except AssertionError:
raise template.TemplateSyntaxError('get_latest_show syntax: {% get_latest_show as varname %}')
varname = None
t, a, varname = args
return GetSlideshowNode(varname=varname)
register.tag(get_latest_show)
The problem is that my slides are being displayed out of order. When I print slideshow.slide.set.all on the page, I see:
[<Slide: Slide 2>, <Slide: Slide 3>, <Slide: Slide 4>, <Slide: Slide 1>]
How do I get the slides to appear in order?
You want the slide_set to be ordered therefor the 'ordering' statement should be on the Slide model.
class Slide(models.Model):
# fields
class Meta:
ordering = ['-title']
This will cause Slide.objects.all() to return a queryset ordered by the title field. That is equivalent to slideshow.slide_set.all()

Get title, nav_title and subtitle

I want to print the fields title, nav_title and subtitle with Typoscript. I saw that there are several possibilities. E.g. data, field, levelfield, leveltitle, ...
Currently I'm using this code (because the only one which works for me so far):
lib.heading = TEXT
lib.heading.dataWrap = <p class="title"> {leveltitle:0} </p>
but I want something with alternatives like this
stdWrap.field = subtitle // nav_title // title
What is the correct way of retrieving these fields?
Edit:
[userFunc = user_isMobile]
page.headerData.10 = TEXT
page.headerData.10.value (
// ...
)
// ...
lib.heading = TEXT
#lib.heading.dataWrap = <p class="title"> {leveltitle:0} </p>
lib.heading {
field = title
wrap = <p class="title"> | </p>
}
lib.subpages = HMENU
lib.subpages {
// ...
}
[global]
The userfunction itself is a function in a php script (user_mobile.php). It makes a user agent detection for mobile devices and returns true or false.
field will get values from the current data which in your context is the data of the current page.
lib.heading = TEXT
lib.heading {
field = subtitle // nav_title // title
wrap = <p class="title">|</p>
}
leveltitle, leveluid, levelmedia, etc. allow you to retrieve some of the data from other pages in the rootline of the current page.
For more information see getText in the documentation.