Reading and writing field values

by Mikko Ohtamaa last modified Nov 11, 2009 07:39 AM
How to access and change the state of your content

Fields and accessors

Normally one creates custom content types using Archetypes Schema pattern. Schema is a list of fields and their properties.

In these examples, we have declared field called "mySomeField" in the schema of the content. Archetypes generates automatically following setters/getters (generated in Archetypes/ClassGen.py):

  • accessor (get method) getMySomeField()
  • mutator (set method) setMySomeField(value)
  • raw accessor (also known as edit accessor, get method which doesn't perform any character encoding) getMySomeFieldRaw()

Automatically generated accessors and mutators can be overriden by field properties. E.g. title accessor is Title() instead of getTitle().


value = myItem.getMagic()

myItem.setMagic(newValue)

Using Field.get and Field.set

Sometimes you cannot access accessor and mutator directly, or you want to wrap returned values for e.g. international character encoding. Field get and set functions do this.

f = myItem.getField("myFunnyField")

# Same Field instance is shared between all content objects so we need to give
# the target content object for Field methods as a parameter

oldValue = f.get(myItem)

f.set(myItem, newValue)
See file Archetypes/Field.py for more details.


Reindexing

For quick object look-ups, Plone maintains search catalogs and indexes. These indexes hold a copy of certain object attributes in search friendly form. In certain situations, when an object is being manipulated, changes are not reflected back to indexes automatically. Thus, the navigation tree, search and some other site functions go out-of-sync and start to behave oddly.

Namely, object.setTitle() doesn't change the object title in navtree which is generated from PathIndex.

To cure the situation call object.reindexObject() after calling mutators.

schema = ATContentTypeSchema.copy() + Schema(
# field list
(
TextField('someField',
widget=StringWidget(
label='Here is a text value',
description="Try to set this",
),
),
IntegerField('someIntegerField')
)

class MyType(ATCTContent):
""" We declare some custom content as example

"""

schema = schema
 
typeDescription= 'MyType custom content type'
meta_type = 'MyType'
archetype_name = 'MyType'

# ...
# Then later on you can manipulate fields
# assuming you have created portal.myfolder.item

myItem = portal.myfolder.myitem

myItem.setSomeField("Moo was here")

# increase counter
intFieldValue = myItem.getSomeIntegerField()
myItem.setSomeIntegerField(intFieldValue + 1)

Getting object type


# Getting object type directly from the class descriptor
type = object.portal_type