quick search:
 

check existence of object

Submitted by: runyaga
Last Edited: 2004-10-14

Category: Python(Script)

Average rating is: 4.0 out of 5 (3 ratings)

Description:
its very common to check existence of a object in a folder.
so here are some ways to do it.

most of the times when you get a object its wrapped in a transparent AcquistionWrapper
which has the following attributes:
aq_parent, aq_inner, aq_base, aq_self, aq_acquire, and aq_explicit

aq_base is not allowed to be used in through-the-web code as it strips
security context, you can only access it through filesystem based code.

seeing Acquistion: http://www.zope.org/Members/4am/aq_trees


Source (Text):
#to check to see if id exists in current folder:
myId = 'id to check for'

#in Script(Python) this will check current folder,
#as well as Acquired objects

if hasattr(context, myId):
    return getattr(context, myId)

#another way is to use the default argument of getattr
return getattr(context, myId, 0)

#in a DTML Method you can
<dtml-if "_.hasattr(this(), myId )"> <dtml-var myId> exists
<dtml-else> doesnt exist
</dtml-if>

#or
<dtml-if "_.getattr(this(), myId, 0)"> <dtml-var myId> exists
<dtml-else> nope
</dtml-if>

#or simply
<dtml-if "myId in objectIds()"> in objectIds()
<dtml-else> not in objectIds()
</dtml-if>


#in a DTML Document
<dtml-if "_.getattr(this().aq_parent, myId, 0)"> <dtml-var myId> exists
<dtml-else> doesnt exist
</dtml-if>

#using objectIds
<dtml-if "myId in this().aq_parent.objectIds()"> in objectIds()
<dtml-else> not in objectIds()
</dtml-if>

#in PageTemplates, NOTE: you are returning the *actual* instance
<span tal:replace="python:test(hasattr(here, myId), getattr(here, myId), 'object not found')" />

# EXPLICIT: 
# getattr/hasattr checks acquistion, if you want to explictly
# check a folder if it has a object you .aq_explicit

# Script(Python)
f = context.myFolder
if getattr(f.aq_explicit, myId, 0): return myId + ' exists!'

#DTML
<dtml-if "_.hasattr(this().aq_explicit, myId)"> <dtml-var myId> exists
<dtml-else> doesnt exist
</dtml-if>

#if you want to check the parent folder you can, go up the acqusition
#chain using aq_parent

f = context.myFolder
if getattr(f.aq_parent.aq_explicit, myId, 0): return 'exists'
return 'nope'

#this will check explicitly myFolder's parent directory for myId


#we can also use ZDOM
f = context.myFolder
if getattr(f.getParentNode().aq_explicit, myId, 0): return 'exists'
return 'nope'

#if you want to programatically acquire lets say, a Property from the Acquistion
#chain you can use 
propertyValue=object.aq_acquire('propertyId')

Explanation:
you will notice alot of python going on ;)

DTMLDocument vs DTMLMethod -- this() in documents give you the
document you are inside, while a DTMLMethod's this() gives you the
context/folder you are calling. or the object you are calling the
Method on. there is quite a bit of info about the differences on
Documents vs Methods and they are very important to understand if you plan
on using DTML. I suggest using PageTemplates.


NOTE: the ZODB is a object database which can be represented as a tree
structure. and objects _contain_ other objects. we can you getattr,
hasattr to traverse the object database. another way is to use ZDOM.
especially if you like the idea of having a XML-like interface mapped
onto the ZODB.

there are many ways to skin the traversal cat. but these are the most
used way, i believe -- and they are quite intuitive.

references: ZDOM.py (in your ZOPE installaton), more info on getattr/hasattr
can be found on python.org.


Comments:

Confusion by efge - 2004-10-14
This is a bit confused, _.hasattr(this(), myId) has *nothing to do* with
myId in objectIds(), as the latter does not use acquisition, and
only looks at "contained" objects, not other methods or attributes.

 
Re: Confusion by runyaga - 2004-10-14
works just fine for me.  this() is the current context and includes
acquistion in its lookup.  I dont see the problem.  
 
Re: Confusion by efge - 2004-10-14
Well for instance suppose you want to test the presence
of "foo" in the current folder. Also suppose it's not there
**but** there is another "foo" higher in the acquisition chain.

Then "foo" in objectIds() will return the correct result (false),
whereas _.hasattr(this(), "foo") will return true, which is not
what we want.
 
Re: Re: Confusion by runyaga - 2004-11-13
your absolutely correct!

_.hasattr(this().aq_expilict, 'foo')

the aq_explicit (as shown above) would check the existence of 'foo' as a object in the current folder (if run in a DTML Method) or if the property 'foo' if this() was a DTML Document.

~runyaga
 
Re: Confusion by efge - 2004-11-13
Actually no, aq_explicit doesn't work like that. The recipe is incorrect.
You have to use ob.aq_inner.aq_explicit.
This came up again recently, see
http://mail.zope.org/pipermail/zope/2004-October/154155.html
or more detailed
http://mail.zope.org/pipermail/zope/2000-December/122978.html


hasProperty by trevor - 2004-10-14
This works for DTML and is easier to read...
<dtml-if "myDocument.hasProperty('myProperty')">yep</dtml-if>