I have three models for countries, provinces and cities. one of URLs includes the city name where a post should go. I could get the name of the city through the URL . In view function, I could find the city name and then I could find the country which the city is belong to. Now, I want to list all cities under this country. My question is how can I do this where there is no direct relation between city and country. The city is related to the province and the province related to the country. The list I want should includes all cities inside the country regardless of the province. How can I do this? is there any possible solution rather than make direct relation between city and country model? Note: I could get the country ID through the variable post_city. The country ID for selected city was 3. Therefor, I want all of cities that are under the country that has an ID of 3.
Example: through the URL: I got post_city variable as Los Angeles. Hence, I want all cities in the USA regardless of state of California. Another example, If the post_city variable was London, then, I want all cities in Britain regardless of the province. the models I have are as follow:
class Country(models.Model):
country_name = models.CharField(max_length=64, unique=True)
def __str__(self):
return "%s" % (self.country_name)
class Province(models.Model):
country_id = models.ForeignKey(Country, on_delete=models.CASCADE)
province_name = models.CharField(max_length=64)
def __str__(self):
return "%s" % (self.province_name)
class City(models.Model):
province_name = models.ForeignKey(Province, on_delete=models.CASCADE)
city_name = models.CharField(max_length=64)
def Country(self):
return self.province_name.country_id.country_name
the view function as follow:
def list_page(request, post_city):
p_c = City.objects.filter(city_name__iexact=post_city).get()
p_p = p_c.province_name
p_country = p_p.country_id
pp=City.objects.all()
print(pp)
context = {
'post_city' : post_city,
'all_p_cities': all_p_cities,
}
return render(request, 'path/to/list_page.html', context )
You can chain multiple related model lookups by using several __
parts in the lookup argument name.
cities_in_narnia = City.objects.filter(province_name__country_id__country_name='Narnia')
Read more in the Django docs: Lookups that span relationships
As a side note. There are some naming conventions you can use that will make your code more readable, especially when seeking help from the online community.
class City(models.Model):
# foreign key fields should be the snake_case or lower case name of the related model class
province = models.ForeignKey(Province, on_delete=models.CASCADE)
# there's no need to prefix field or attribute names with the class name
# City.city_name is superfluous. City.name is perfectly clear.
name = models.CharField(max_length=64)
# methods and attributes should also be snake_case, only use CapitalCase for class names.
@property
def country_name(self):
return self.province.country.name
If you follow these naming conventions, the filter lookup will also be readable and concise.
cities_in_narnia = City.objects.filter(province__country__name='Narnia')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.