Populating model properties dynamically from a javascript call
Problem Description:
1] I have a model with country and city properties
class UserReportedData(db.Model):
#country selected by the user, this will also populate the drop down list on the html page
country = db.StringProperty(default='Afghanistan',choices=['Afghanistan','Aring land
Islands','Albania'])
#city selected by the user
city = db.StringProperty()
Associated form
class UserReportedDataForm(djangoforms.ModelForm):
class Meta:
model = UserReportedData
2] With help from stackoverflow (thanks Chris, posting: GeoIP with google app engine and python), i have figured out how to use javascript in the html page to find out the country and city for a user. The following code is successfully able to print the values of country and city on the page
<!-- including the geoip javascript library -->
<script
src="http://j.maxmind.com/app/geoip.js"
type="text/javascript">
</script>
<script type="text/javascript">
if (window.geoip_country_name) {
document.write(geoip_country_name())
document.write(geoip_city())
}
</script>
3] Now when the page is displayed the country and city text box and default values are coming from the django form (sorry cant post a image because of restrictions)
Question:
I want the country and city data of the user to be filled in the country and city text box. So, somehow the python form or model should be able to call the javascript code and get the country and city data for the user.
Thanks,
[EDIT#1] Edit based on the approach suggested by @Haochi
The following are the id's that are generated by the djangoforms
<select name="country" id="id_country">
<input type="text" name="city" id="id_city" />
Tried the following javascript in the html page
<script type="text/javascript">
if (window.geoip_country_name) {
document.getElementById("id_country").value = geoip_country_name();
document.getElementById("id_city").value = geoip_city();
document.write("this is a javasctipt print"); /* this prints properly*/
document.write(document.getElementById("id_country").value);
document.write(document.getElementById("id_city").value);
}
</script>
This however, didn't fill in the values for id_country and id_city text fields appropriately.
[EDIT#3] This is how the HTML file looks like, I have now moved the GEOIP calculation from server side to the client side
<!-- Text box for city, later on in the design this will be a drop down box -->
<p> S开发者_运维知识库elect City: </p>
<div>
<input type="text" name="city" id="city">
<!-- By default, we will select users city -->
<script type="text/javascript" language="JavaScript">
document.getElementById("city").value = geoip_city()
</script>
</div>
<p> Select Country: </p>
<select name="selCountry" id="country">
<!-- By default, we will select users country -->
<script type="text/javascript" language="JavaScript">
document.write("<option value=\"" + geoip_country_name() + "\" selected>"
</script>
<option value="United States">
United States
</option>
<option value="United Kingdom">
United Kingdom
</option>
I believe the best practice is to move all javascript to a separate file , i need to try this out and modify the HTML code accordingly.
Assuming your IDs for those two inputs are country and city:
document.getElementById("country").value = geoip_country_name()
document.getElementById("city").value = geoip_city()
I wrote the following python class to find the country and city for the user. This is working, if someone finds any issues or somethings that can be changed for efficiency, please let me know
from google.appengine.api import urlfetch
#class that is used for geo ip functionality of the application
class GeoIpLocator:
#method that will return the country city dictionary based on users GeoIP location
#dictionary format {"country_name": "USA", "city":"chicago"}
def get_country_city_dictionary(self):
url = "http://j.maxmind.com/app/geoip.js"
result = urlfetch.fetch(url)
if result.status_code == 200:
keep = ['country_name', 'city']
results = dict([x for x in re.findall("geoip_(.*?)\(.*?\'(.*?)\'", result.content) if x[0] in keep])
results.update({'source': 'mmind'})
if results:
return results
else:
return {}
[EDIT#1] This will not work and will return the IP of the server on which the python app loads up, thanks to @Calvin for pointing this out.
精彩评论