|
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: [hidden email] http://www.vsb.cz _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
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 [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
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?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.
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
Best Regards Lumir
-- Lumír Jasiok VSB-TU Ostrava - Computer centre Tel: +420 59 732 3189 E-mail: [hidden email] http://www.vsb.cz _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
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 [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
| Powered by Nabble | Edit this page |
