Hello!
I created an app using the wizard. I'd like to create a general view
for a record and its sub-records (1:n relation).
Unfortunately I tend to creating Spaghetti-code and the solution is
quite messy.
Could you suggest any solution that is simpler?
Is it possible to reuse this for different views and / or not creating
an own view for everything? The wizard generated more than 30 views!
Thank you!
L.
# In /models/db_wizard.py:
########################################
db.define_table( 't_videos',
Field( 'id', 'id', represent=lambda id:SPAN(id,' ', A( 'view',
_href=URL( 'videos_read', args=id)))),
Field( 'f_title', type='string', label=T( 'Title')),
Field( 'f_studio_id', db.t_studios, label=T( 'Studio Id')),
Field( 'f_date_produced', type='date',
widget=SQLFORM.widgets.date.widget, label=T( 'Date Produced')),
Field( 'f_date_released', type='date',
widget=SQLFORM.widgets.date.widget, label=T( 'Date Released')),
Field( 'active', 'boolean', default=True,
label=T( 'Active'),writable=False,readable=False),
Field( 'created_on', 'datetime', default=request.now,
label=T( 'Created On'),writable=False,readable=False),
Field( 'modified_on', 'datetime', default=request.now,
label=T( 'Modified On'),writable=False,readable=False,
update=request.now),
format='%(f_title)s',
migrate=settings.migrate
)
########################################
db.define_table( 't_shots',
Field( 'id', 'id', represent=lambda id:SPAN(id,' ', A( 'view',
_href=URL( 'shots_read', args=id)))),
Field( 'f_video_id', db.t_videos, label=T( 'Video ID')),
Field( 'f_time_start', type='time',
widget=SQLFORM.widgets.time.widget, label=T( 'Time Start')),
Field( 'f_time_end', type='time',
widget=SQLFORM.widgets.time.widget, label=T( 'Time End')),
Field( 'active', 'boolean', default=True,
label=T( 'Active'),writable=False,readable=False),
Field( 'created_on', 'datetime', default=request.now,
label=T( 'Created On'),writable=False,readable=False),
Field( 'modified_on', 'datetime', default=request.now,
label=T( 'Modified On'),writable=False,readable=False,
update=request.now),
format='%(f_video_id)s',
migrate=settings.migrate
)
# In /controllers/default.py
#[...]
topsub = local_import( 'topsub')
#[...]
def videos_read():
form, sub_sqltable = topsub.topsub_helper(
db,
crud,
db.t_videos,
request.args(0),
't_shots',
'f_video_id',
[ 't_shots.id', 't_shots.f_time_start', 't_shots.f_time_end'],
{ 'orderby':'f_time_start'},
sub_link = 'VideoDB/default/shots_read'
)
return dict( form=form, sub_sqltable=sub_sqltable)
# In /modules/topsub.py
#[...]
def sublink( sub_link):
# Doesn't work, because SQLTABLE( linkto... adds the table name
(../default/shots_read/t_shots/[ID])
application, controller, function = sub_link.split('/')
return URL( a=application, c=controller, f=function)
def topsub_helper( db, crud, t_top, t_top_id, t_sub,
str_sub_reference_field, fields, attributes, sub_link):
top_record = t_top( t_top_id) or redirect( URL( 'error'))
top_form = crud.read( t_top, top_record)
sub_table = db[ t_sub]
sub_reference_field = sub_table[ str_sub_reference_field]
sub_rows = db( sub_reference_field ==
top_record).select( sub_table.ALL, **attributes)
sub_sqltable = SQLTABLE( sub_rows, headers='labels',
linkto=sublink( sub_link), columns=fields, orderby=True)
return top_form, sub_sqltable
# In /views/default/videos_read.html
{{extend 'layout.html'}}
<h2>Movies</h2>
{{=A(T('edit
videos'),_href=URL('videos_update',args=request.args(0)))}}
<br/>
{{=form}}
{{for t,f in db.t_tags._referenced_by:}}
{{if not t[-8:]=='_archive':}}
[{{=A(t[2:],_href=URL('%s_select'%t[2:],args=(f,form.record.id)))}}]
{{pass}}
{{pass}}
<h2>Shots</h2>
{{if sub_sqltable:}}
{{=sub_sqltable}}
{{else:}}
{{=TAG.blockquote(T('No Data'))}}
{{pass}}