I’d like help in building a universal address function for all countries. I’m hoping that it would prove useful to other programmers so it could be posted to Slices. The data model is finished, just need help with controller.
BACKGROUND Different countries have different geo-political divisions, and the number of divisions differs, e.g., United States has 3: city, county, state, federal. Viet Nam has 4: district, ward, province, township. To handle this I've created a lookup table that abstracts and stacks geo-political subdivision types into virtual fields. MODELS db.define_table('GeoPoliticalDivision', ## E.g., US City, VN District Field('countryCode','reference Country'), ## E.g., US Field('geoPoliticalName','string')) ## E.g., City' Sample data United States of America US City United States of America US County United States of America US State Viet Nam District Then, table below takes the data from above table, and adds the specific information for a specific address. db.define_table('AddressGeoPoliticalDivision', ## This 1:M intersection table is child of Address table. Address table stores country name, postal code and first 3 lines of address like “street”. This table stores the different geoPolitical divisions. Example: Address #1, US city, Sacramento. Address #1, US county, Yolo. Address #1, US state, California. Field('addressID','reference Address'), Field('geoPoliticalDivisionID','reference GeoPoliticalDivision'), ## E.g., VN city, or, US county. Field('geoPoliticalDivisionData','string')) ## this contains name of the division, e.g., “Chicago” Sample data 30 Humboldt Drive - US City - Arcata 30 Humboldt Drive - US County - Humboldt 30 Humboldt Drive - US State - California The above table is only part of a party’s address. It is a 1:M child of the Address table below db.define_table('Address', Field('addressLine_1','string'), Field('addressLine_2','string'), Field('addressLine_3','string'), Field('zipOrPostalCode','string'), Field('countryCode','string',label='Country')) Another table, db.PartyAddressIntersection, links an address to a party. To populate an address, the code has to loop through the virtual 'GeoPoliticalDivision' fields for that country to enable user to fill them out. That’s the part I need help with. CONTROLLER Here is a join that shows how db.AddressGeoPoliticalDivision works query = (db.Party.id == db.auth_user.partyID) & (db.PartyAddressIntersection.partyID==db.Party.id) & (db.PartyAddressIntersection.addressID==db.Address.id) & (db.PartyAddressIntersection.addressTypeID==db.AddressType.id) & (db.AddressGeoPoliticalDivision.addressID==db.Address.id) Here’s most of the code to add an address. What is missing is the code for how to loop through db.GeoPoliticalDivision for the correct country and populate db.AddressGeoPoliticalDivision fields. @auth.requires_login() def add_new_government_organization(): db.ObjectSuperType.objectTypeID.default = 1 ## sets up db so object type is designated as a party (not a component) db.Party.partyTypeID.default = 2 ## sets up db so it's an organization (not a person) db.Organization.organizationPrimaryTypeID.default = 1 ## sets up Organization table so primary type is "Government" db.ObjectSuperType.objectTypeID.readable = db.ObjectSuperType.objectTypeID.writable = False ## don't let user see field thinking they have to fill it in ##db.Organization.termsAndConditions.readable = db.Organization.termsAndConditions.writable = False ## db.Party.objectID.readable = db.Party.objectID.writable = False ## don't let user see field thinking they have to fill it in db.Organization.partyID.readable = db.Organization.partyID.writable = False ## don't let user see field thinking they have to fill it in db.GovOrgJurisdiction.organizationID.readable = db.GovOrgJurisdiction.organizationID.writable = False db.Organization.organizationPrimaryTypeID.readable = db.Organization.organizationPrimaryTypeID.writable = False ## don't let user see field thinking they have to fill it in db.Party.partyTypeID.readable = db.Party.partyTypeID.writable = False ## don't let user see field thinking they have to fill it in db.PartyAddressIntersection.addressID.readable = db.PartyAddressIntersection.addressID.writable = False ## don't let user see field db.Address.id.readable = db.Address.id.writable = False ## don't let user see field form=SQLFORM.factory(db.ObjectSuperType,db.Party,db.Organization, db.PartyAddressIntersection, db.Address, db.GovOrgJurisdiction) if form.process().accepted: objectID = db.ObjectSuperType.insert(**db.ObjectSuperType._filter_fields(form.vars)) form.vars.objectID=objectID partyID = db.Party.insert(**db.Party._filter_fields(form.vars)) form.vars.partyID=partyID organizationID = db.Organization.insert(**db.Organization._filter_fields(form.vars)) form.vars.organizationID=organizationID addressID = db.Address.insert(**db.Address._filter_fields(form.vars)) form.vars.addressID=addressID partyID = db.PartyAddressIntersection.insert(**db.PartyAddressIntersection._filter_fields(form.vars)) organizationID = db.GovOrgJurisdiction.insert(**db.GovOrgJurisdiction._filter_fields(form.vars)) response.flash='Thanks for filling the form' return dict(form=form) If you send me your address, I can send the whole package packed in Windows format. My email is here: http://www.gov-ideas.com/contact.htm Thanks, Alex Glaros -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.