[Grok-dev] Multiple models inside container

Lumir Jasiok lumir.jasiok at vsb.cz
Wed Mar 23 08:24:36 EDT 2011


On 3/21/11 4:53 PM, Martijn Faassen wrote:
> 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.
>
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
> 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-dev at zope.org
> https://mail.zope.org/mailman/listinfo/grok-dev


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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/grok-dev/attachments/20110323/26aa591c/attachment.html 


More information about the Grok-dev mailing list