CRUD and TG

0 views
Skip to first unread message

Ronald Jaramillo

unread,
Oct 12, 2005, 3:03:21 PM10/12/05
to turbo...@googlegroups.com
Hi,
IMHO doing proper form generation is difficult. The first 90% are
usually very easy but the last bit is a PITA. You end up fighting
against the framework in order to get things 'just right'. And
usually this involve digging trough several abstraction layers or
circumventing the framework altogether.
CatWalk is suppose to be a simple viewer - an aid during development,
like PhpMyAdmin, but at the ORM level - not the db.

Rather than complete form generation I will like to work with some
kind of 'smart' view. This could be bundles of controller code, Kid
templates and Mochi stuff, that understand how to render certain
objects.
This bundles could be distributed as an egg so people could drop them
into their app.
A view could implement some kind of default presentation based on the
standard SQLObject types and let your app register as delegate for
certain aspects of the presentation and user interaction.
Personally I will love to se a powerful grid view that knew how to
render different kinds of tabular data and wasn't ashamed to ask when
it didn't ; )

For example when displaying an object in CatWalk, if the object has a
ForeignKey, it will show the referred object's id. If the referred
object was, let's say, a 'Book' object, the obvious label to display
will be the book title. But in another context the best label to
display in a view could be the ISBN number.
That's why I think that the "adding 'metadata' to my models" approach
can only take you that far. I will rather see a system where the view
will let you implement a delegate like
'columnToUseAsLabelForForeignKey' where you could return 'title',
'ISBN' or another column name based on the context.

Well, enough rambling, otherwise I share Ian's view about pushing (or
rather not pushing) some CRUD into TG 0.9.

Cheers
Ronald Jaramillo

Ian Bicking

unread,
Oct 12, 2005, 3:45:41 PM10/12/05
to turbo...@googlegroups.com
Ronald Jaramillo wrote:
> Rather than complete form generation I will like to work with some kind
> of 'smart' view. This could be bundles of controller code, Kid
> templates and Mochi stuff, that understand how to render certain objects.
> This bundles could be distributed as an egg so people could drop them
> into their app.
> A view could implement some kind of default presentation based on the
> standard SQLObject types and let your app register as delegate for
> certain aspects of the presentation and user interaction.
> Personally I will love to se a powerful grid view that knew how to
> render different kinds of tabular data and wasn't ashamed to ask when
> it didn't ; )

This is an ideal place for generic functions. E.g.:

@dispatch.generic()
def html(obj, context):
# Use XML() to return HTML, not just a string
return repr(obj)

@html.when('isinstance(obj, SQLObject)')
def sql_html(obj, context):
rows = []
for column in obj.sqlmeta.columnList:
value = getattr(obj, column.name)
restore = context.push_attr(sqlobject=obj, column=column,
column_name=column.name,
short=True)
try:
rows.append('<tr><td>%s</td><td>%s</td></tr>' % (desc,
value))
finally:
restore.pop_attr()
return XML('<table>%s</table>' % '\n'.join(rows))

and so forth. This is a really easy way to implement both general rules
(e.g., use repr()), and specific rules. And you can do really specific
overrides:

@html.when('isinstance(obj, Article) and context.short')
def short_html(obj, context):
return obj.title

# Show the beginning of long texts...
@html.when('context.short and isinstance(obj, (str, unicode)) and
len(obj) > 40')
def short_text(obj, context):
return obj[:40]+'...'

# but show the beginning and end of article bodies
@html.when('isinstance(context.sqlobject, Article) and
context.column_name="body" and context.short')
def short_article_body(obj, context):
return obj[:20]+'...'+obj[20:]


And hopefully from this it should be clear how someone using other kinds
of objects (that aren't SQLObject objects) could

> For example when displaying an object in CatWalk, if the object has a
> ForeignKey, it will show the referred object's id. If the referred
> object was, let's say, a 'Book' object, the obvious label to display
> will be the book title. But in another context the best label to
> display in a view could be the ISBN number.
> That's why I think that the "adding 'metadata' to my models" approach
> can only take you that far. I will rather see a system where the view
> will let you implement a delegate like
> 'columnToUseAsLabelForForeignKey' where you could return 'title',
> 'ISBN' or another column name based on the context.

I think generic functions can handle this much more cleanly than a
collection of attributes like columnToUseAsLabelForForeignKey. The key
being the magical context argument (which is like
formencode.fields.Context, but what I describe here doesn't match it
exactly); that allows you to make specific overrides based on the
context of where you are rendering an object. The way generic functions
choose an implementation is also a very good match for this, I think.

--
Ian Bicking / ia...@colorstudy.com / http://blog.ianbicking.org

Ronald Jaramillo

unread,
Oct 12, 2005, 3:58:38 PM10/12/05
to turbo...@googlegroups.com
Well it looks like now is the time for me to re-read David last
couple of Charming Python columns. First time I read about this, it
sounded nifty but I picture it in the context of workflows. Anyway
thanks for the input Ian.
Cheers,
Ronald

Kevin Dangoor

unread,
Oct 18, 2005, 12:31:06 AM10/18/05
to turbo...@googlegroups.com
On 10/12/05, Ronald Jaramillo <ron...@checkandshare.com> wrote:
> IMHO doing proper form generation is difficult. The first 90% are
> usually very easy but the last bit is a PITA. You end up fighting
> against the framework in order to get things 'just right'. And
> usually this involve digging trough several abstraction layers or
> circumventing the framework altogether.

Agreed. Let's not make that particular mistake.

To Rails' credit, scaffolding gives you something to look at right
away and then generates the code so that you can start modifying. As I
understand it, though, there is still a fair bit of magic to
understand.

My thoughts are more along the lines of library code for the
controllers *and* the Kid templates that get you going and allow you
to customize in a way that is not magical.

> Rather than complete form generation I will like to work with some
> kind of 'smart' view. This could be bundles of controller code, Kid
> templates and Mochi stuff, that understand how to render certain
> objects.
> This bundles could be distributed as an egg so people could drop them
> into their app.
> A view could implement some kind of default presentation based on the
> standard SQLObject types and let your app register as delegate for
> certain aspects of the presentation and user interaction.

This sounds like what I was thinking of as well.

> Personally I will love to se a powerful grid view that knew how to
> render different kinds of tabular data and wasn't ashamed to ask when
> it didn't ; )

raise IDontKnowHowToRender :)

> Well, enough rambling, otherwise I share Ian's view about pushing (or
> rather not pushing) some CRUD into TG 0.9.

I think CRUD is important to get into TurboGears sooner than later, if
for no reason other than putting a stake in the ground saying "here's
something" and giving people a chance to poke holes in it. I don't,
however, intend to delay TurboGears 1.0, because I think TurboGears is
useful already.

My thought right now is to explore CRUD a bit, see what kind of code
turns up and then decide whether it will truly make it into 0.9/1.0.

Kevin

--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: k...@blazingthings.com
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com
Reply all
Reply to author
Forward
0 new messages