Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Multiple models inside container
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  4 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Lumir Jasiok  
View profile  
 More options Mar 17 2011, 8:32 am
From: Lumir Jasiok <lumir.jas...@vsb.cz>
Date: Thu, 17 Mar 2011 13:32:17 +0100
Local: Thurs, Mar 17 2011 8:32 am
Subject: [Grok-dev] Multiple models inside container
Hi,

right now I have small app with one model, one AddForm as is below:

class Awis(grok.Application, grok.Container):
     def __init__(self):
         super(Awis, self).__init__()
         self.title = "AWIS"
         self.store_id = 0

class IStore(interface.Interface):
     store_id = schema.Int(title=u'Store ID', default=1)
     title = schema.TextLine(title=u'Name', required=True)
     address = schema.Text(title=u'Address')
     storesman = schema.TextLine(title=u'Storesman', required=True)
     description = schema.Text(title=u'Description')

class Store(grok.Model):
     grok.implements(IStore)

class AddStore(grok.AddForm):
     grok.context(Awis)
     form_fields = grok.AutoFields(IStore).omit('store_id')

     @grok.action('Add Store')
     def add(self,**data):
         self.context.store_id = self.context.store_id + 1
         data['store_id'] = self.context.store_id
         store = Store()
         self.applyData(store,**data)
         store.store_id = self.context.store_id
         self.context[str(self.context.store_id)] = store
         self.context._p_changed = True
         self.redirect(self.url(store))

But now I want to add Employee class, that will be similar to Store
class. Inside Employee AddForm I want to save inside Awis context. After
that I will not be able to recognize which ID belongs to Store object
and Which to Employee object. How can I correctly save Store objects and
Employees objects inside Awis container and be able to recognize them.
Using dictionaries - self.context.stores and self.context.employees? -
but how can I access those dictionaries from TAL?

Or am I completely wrong and there is better way to do it?

Best Regards

Lumir

--
  Lumír Jasiok
  VSB-TU Ostrava - Computer centre
  Tel: +420 59 732 3189
  E-mail: lumir.jas...@vsb.cz
  http://www.vsb.cz

_______________________________________________
Grok-dev mailing list
Grok-...@zope.org
https://mail.zope.org/mailman/listinfo/grok-dev


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Martijn Faassen  
View profile  
 More options Mar 21 2011, 11:53 am
From: Martijn Faassen <faas...@startifact.com>
Date: Mon, 21 Mar 2011 16:53:18 +0100
Local: Mon, Mar 21 2011 11:53 am
Subject: Re: [Grok-dev] Multiple models inside container
On 03/17/2011 01:32 PM, Lumir Jasiok wrote:
[snip]

> But now I want to add Employee class, that will be similar to Store
> class. Inside Employee AddForm I want to save inside Awis context. After
> that I will not be able to recognize which ID belongs to Store object
> and Which to Employee object. How can I correctly save Store objects and
> Employees objects inside Awis container and be able to recognize them.
> Using dictionaries - self.context.stores and self.context.employees? -
> but how can I access those dictionaries from TAL?

> Or am I completely wrong and there is better way to do it?

There are different solutions.

You could create two containers and make them @grok.traversible and
store them in the Awis object, one for Employee and one for Store.  You
might need to set up the sub-containers in an event handler for the add
event to make it set up right; not sure it works in the __init__(). This
would, I think, be the simplest approach and makes sure your objects are
in different containers altogether. Container making explicit subclasses
for the subcontainers, such as EmployeeContainer and StoreContainer, so
that you can create specific views for them and such later.

Alternatively you could indeed store everything withint Awis. One way to
distinguish the two is to simply use Python's isinstance() and loop
through the things in the container in some helper method:

def get_employees(self):
   employees = []
   for value in self.values():
       if isinstance(value, Employee):
            employees.append(value)
   return employees

This won't be very fast if you have *many* employees or stores, though,
as it'll have to loop through them each time. Instead, you could
consider using the catalog. You can then index these things in the
catalog, and look them up quickly in the index. You'd probably have to
set up a "model_type"  (or whatever name you pick) attribute on the
Store and Employee classes that you can index first:

class Employee(...):
    model_type = 'employee'

setting up the catalog is something you need to google for.

Note that you can still use the catalog even if you spread things into
different containers as sketched out above.

Regards,

Martijn

_______________________________________________
Grok-dev mailing list
Grok-...@zope.org
https://mail.zope.org/mailman/listinfo/grok-dev


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lumir Jasiok  
View profile  
 More options Mar 23 2011, 8:24 am
From: Lumir Jasiok <lumir.jas...@vsb.cz>
Date: Wed, 23 Mar 2011 13:24:36 +0100
Local: Wed, Mar 23 2011 8:24 am
Subject: Re: [Grok-dev] Multiple models inside container

On 3/21/11 4:53 PM, Martijn Faassen wrote:

OK, I understand concept and I like it. This is what I looking for. But
I am not familiar with grok.traversable(). Sorry for trouble you, but do
you have some small example? Will be possible edit objects inside
container using EditForm? AFIK grok.context() inside EditForm should be
just Application or Model object types?
> Alternatively you could indeed store everything withint Awis. One way to
> distinguish the two is to simply use Python's isinstance() and loop
> through the things in the container in some helper method:

> def get_employees(self):
>     employees = []
>     for value in self.values():
>         if isinstance(value, Employee):
>              employees.append(value)
>     return employees

Temporarily I fix it like this:

class AddStore(grok.AddForm):
     grok.context(Awis)
     form_fields = grok.AutoFields(IStore)

     @grok.action('Add Store')
     def add(self,**data):
         self.context.store_id = self.context.store_id + 1
         data['store_id'] = self.context.store_id
         store = Store()
         self.applyData(store,**data)
         name = "store-" + str(self.context.store_id)
         # Set the right store_id
         store.store_id = self.context.store_id
         self.context[name] = store
         self.context._p_changed = True
         return self.redirect(self.url(self.context))

class AddEmployee(grok.AddForm):
     grok.context(Awis)
     form_fields = grok.AutoFields(IEmployee)

     @grok.action('Add Employee')
     def add(self,**data):
         self.context.employee_id = self.context.employee_id + 1
         data['employee_id'] = self.context.employee_id
         employee = Employee()
         self.applyData(employee,**data)
         name = "employee-" + str(self.context.employee_id)
         self.context[name] = employee
         self.context._p_changed = True
         return self.redirect(self.url('employees'))

So I have different names and different ID's for different objects
inside Awis context. But I have trouble on page template side. I am
trying iterate over context/values and using conditional elements to
display or not object.

stores.pt sample code:

<body>
<h1>Stores</h1>
<tal:block repeat="store context/values">
<div tal:condition="python:isinstance(store,Store)">
<ul>
<li tal:content="python:store">Object</li>
<li tal:content="store/title">Title</li>
<li tal:content="store/storesman">Storesman</li>
<li tal:content="store/description">Description</li>
<a tal:define="url python:view.url('deletestore')" tal:attributes="href
string:${url}?store=${store/store_id}"/>Delete<a/>
<a tal:attributes="href string:store-${store/store_id}/edit">Edit</a>
</ul>
</div>
</tal:block>
<a  href="./addstore">Add Store</a>
<p />
<a  href="./index">Main page</a>
</body>

This code doesn't work. Problem is with isinstance(store,Store)
evaluation. It always failed. I tried isinstance(store,context/Store)
without success. Only working code is isinstance(store,object). But this
is useless. How can I test if repeated object is Store or Employee
object correctly inside page templates?

FYI, line:

<li tal:content="python:store">Object</li>

is evaluated as

    * <awis.app.Store object at 0x3bb4848>

Best Regards

Lumir

--
  Lumír Jasiok
  VSB-TU Ostrava - Computer centre
  Tel: +420 59 732 3189
  E-mail: lumir.jas...@vsb.cz
  http://www.vsb.cz

_______________________________________________
Grok-dev mailing list
Grok-...@zope.org
https://mail.zope.org/mailman/listinfo/grok-dev


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Martijn Faassen  
View profile  
 More options Mar 23 2011, 7:06 pm
From: Martijn Faassen <faas...@startifact.com>
Date: Thu, 24 Mar 2011 00:06:13 +0100
Local: Wed, Mar 23 2011 7:06 pm
Subject: Re: [Grok-dev] Multiple models inside container
On 03/23/2011 01:24 PM, Lumir Jasiok wrote:

> OK, I understand concept and I like it. This is what I looking for. But
> I am not familiar with grok.traversable(). Sorry for trouble you, but do
> you have some small example? Will be possible edit objects inside
> container using EditForm?

Yes, it won't matter where the objects are, as long as the EditForm's
context is the objects you want to edit, it should work.

> AFIK grok.context() inside EditForm should be
> just Application or Model object types?

Generally for an edit form you'd want the context to be the object you
want to edit, and for an add form you'd want the context to be the
collection (container) of objects you want to add to.

For an example, check here:

http://grok.zope.org/doc/1.3/reference/directives.html#grok-traversable

but for containers, you'd basically do this:

class MyApplication(grok.Application, grok.Model):
     grok.traversable('foo')
     grok.traversable('bar')

     def __init__(self):
          self.foo = FooContainer()
          self.bar = BarContainer()

Now myapp/foo and myapp/bar are your containers. You'd probably have add
forms like this: myapp/foo/add and myapp/bar/add, and you'd have edit
forms like this myapp/foo/1553/edit and myapp/bar/515353/edit. You'd
make the add form for 'Foo' objects the context of FooContainer, and the
same for bar and BarContainer.

Note that as I said previously, you might need an event to set up these
containers instead, I'm not sure initialization will go nicely here -
not 100% sure.

You could also choose to let MyApplication itself be a container, in
which case you wouldn't need grok.traversable:

class MyApplication(grok.Application, grok.Container):
     def __init__(self):
          self['foo'] = FooContainer()
          self['bar'] = BarContainer()

but this design is a bit less nice, as really the application isn't
really a container people can add and remove things to.

[snip]

> This code doesn't work. Problem is with isinstance(store,Store)
> evaluation. It always failed. I tried isinstance(store,context/Store)
> without success. Only working code is isinstance(store,object). But this
> is useless. How can I test if repeated object is Store or Employee
> object correctly inside page templates?

I would never do this within a template. I'd always write a helper
method in Python to do this, and then call this from your template
instead. I'd simply make a method that returns all stores. That makes it
easier to test too. Page templates are restricted in various ways that I
just don't want to have to deal with. In this case I don't know where
the 'Store' class comes from in the template.

But anyway, if you change your application's design so that the stores
are in a separate container, things will become simpler.

Regards,

Martijn

_______________________________________________
Grok-dev mailing list
Grok-...@zope.org
https://mail.zope.org/mailman/listinfo/grok-dev


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »