A] Summary:
Using get or insert functions for one model for many django models, checking if there is a record or link before adding a new one.
B] Details:
1] I have the following django model structure structure structure (one) for the City (many)
2] I am using ModelForm to display the form on the html page. Forms are passed as template values, and then the template values ββare displayed on the html page
3] When a request for sending arrives, the code retrieves the data of the form of the country and city, validates and stores it.
C] Problem / item I need help:
1] I want to use the get_or_insert function with my country and city relations
2] In principle, I want to check if the country database of the country selected by the user exists in the country,
2.1] If a country exists, check if a city record exists for the selected country.
2.1.1] If a city record exists, we are good, there is no need to add another record
2.1.2] if the city record does not exist, create a city record and associate the country with it
2.2] if the country does not exist, create a country, create a city record and associate the city record with the country record.
C] Code excerpts:
1] Models and forms -
class UserReportedCountry(db.Model):
country_name = db.StringProperty( required=True,
choices=['Afghanistan','Aring land Islands']
)
class UserReportedCity(db.Model):
country = db.ReferenceProperty(UserReportedCountry, collection_name='cities')
city_name = db.StringProperty(required=True)
class UserCountryForm(djangoforms.ModelForm):
class Meta:
model = UserReportedCountry
class UserCityForm(djangoforms.ModelForm):
class Meta:
model = UserReportedCity
exclude = ('country', )
2], which prints forms -
user_country_form and user_city_form are passed from python code as template values
__TEMPLATE_USER_COUNTRY_FORM = 'user_country_form'
__TEMPLATE_USER_CITY_FORM = 'user_city_form'
def get(self):
template_values = {
self.__TEMPLATE_USER_COUNTRY_FORM: UserCountryForm(),
self.__TEMPLATE_USER_CITY_FORM: UserCityForm()
}
self.response.out.write(template.render(self.__MAIN_HTML_PAGE, template_values))
3] HTML code excerpt showing the values ββof the template on the html page
<div id="userDataForm">
<form method="POST" action="/UserReporting">
<table>
{{ user_country_form }}
{{ user_city_form }}
</table>
<input type="submit" name="submit" value= "submit">
</form>
</div>
3] Code excerpt for saving data -
def post(self):
self.store_user_data()
self.redirect('/')
def store_user_data(self):
user_reported_country = UserCountryForm(self.request.POST)
user_reported_city = UserCityForm(self.request.POST)
if (user_reported_country.is_valid() and user_reported_city.is_valid()):
country_entity = user_reported_country.save()
city_entity = user_reported_city.save(commit=False)
city_entity.country = country_entity
city_entity.put()
return
else:
return
Thanks for reading.
[Change # 1]
@Torsten, get_or_insert, StackOverflow (http://stackoverflow.com/questions/4812832/get-or-create-matching-key-and-user-python-app -engine) key_name get_or_insert
:
def store_user_data(self):
user_reported_country = UserCountryForm(self.request.POST)
user_reported_city = UserCityForm(self.request.POST)
if (user_reported_country.is_valid() and user_reported_city.is_valid()):
country_record = self.store_country_data()
city_record = self.store_city_data(country_record)
return
else:
return
def store_country_data(self):
user_reported_country_name = self.request.POST['country_name']
key_name = self.sanitize_key_name(user_reported_country_name)
country_entity = UserReportedCountry.get_or_insert(key_name, country_name = user_reported_country_name)
country_entity.put()
return country_entity
def store_city_data(self, country_record):
user_reported_city_name = self.request.POST['city_name']
key_name = self.sanitize_key_name("%s:%s" % (country_record.country_name, str(user_reported_city_name)) )
city_entity = UserReportedCity.get_or_insert(key_name,
city_name = user_reported_city_name,
country= country_record)
city_entity.put()
return city_entity
def sanitize_key_name(self,key_name):
return re.sub(r'\s', '', key_name.lower())
: - , - ?