简体   繁体   English

如何从数据库中获取一个国家的城市列表?

[英]How to get a list of cities in a country from database?

I have 2 models, City and Country.我有 2 个模型,城市和国家。 I want to show cities in the country on a page based on the country selected.我想根据所选国家/地区在页面上显示该国家/地区的城市。 I tried to query the Country model passing it to the City model to find all cities related to the country but currently, pages show all cities no matter what is the country.我尝试查询 Country 模型,将其传递给 City 模型以查找与该国家/地区相关的所有城市,但目前,无论哪个国家/地区,页面都会显示所有城市。

How I can show cities in one country when the user selects the country from the page?当用户从页面中选择国家时,如何显示一个国家的城市?

Any help or suggestions are highly appreciated.任何帮助或建议都非常感谢。

models.py模型.py

class City(models.Model):
    country = models.ForeignKey('Country', on_delete=models.CASCADE, related_name='country')
    name = models.CharField(max_length=90, verbose_name='City name')
    slug = models.SlugField(null=True, unique=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('city:cities', kwargs={'slug': self.slug})

     def save(self, *args, **kwargs): 
         if not self.slug:
             self.slug = slugify(self.name)
         return super().save(*args, **kwargs)

class Country(models.Model):
    country_name = models.CharField(max_length=50, verbose_name='Country name',unique=True)
    slug = models.SlugField(null=True, unique=True)

    def __str__(self):
        return self.country_name

    def get_absolute_url(self):
       return reverse('city:cities', kwargs={'slug': self.slug})

    def save(self, *args, **kwargs): 
         if not self.slug:
             self.slug = slugify(self.country_name)
         return super().save(*args, **kwargs)

views.py视图.py

class CountriesListView(ListView):
    template_name = "countries.html"
    model = Country

    context_object_name = "countries"

class CitiesListView(ListView):
    template_name = "cities_list.html"
    model = City

    context_object_name = "cities"

    def get_context_data(self, *args, **kwargs):
        context = super(CitiesListView, self).get_context_data(*args,**kwargs)
        countries = Country.objects.all()
        cities = City.objects.filter(country__in=countries)
        context['cities'] = cities
        return context

templates模板

# countries.html

<h1>Countries</h1>

{% for country in countries %}
  <h3><a href="{% url 'city:cities' country.slug %}">{{ country.country_name }}</h3>
{% endfor %}


# cities_list.html

<h1>Cities</h1>

{% for city in cities %}
  <div>
        <h3><a href="{% url 'city:details' city.slug %}">{{ city }}</a></h3>
  </div>  
{% endfor %}

The related_name=… parameter [Django-doc] is the name of the relation in reverse , so to access the City objects of a specific Country . related_name=…参数 [Django-doc]反向关系的名称,因此可以访问特定CountryCity对象。 Therefore naming it Country is not a good idea.因此,将其命名为Country并不是一个好主意。 You can rename it to cities for example:您可以将其重命名为cities ,例如:

class City(models.Model):
    country = models.ForeignKey(
        'Country',
        on_delete=models.CASCADE,
        related_name='cities'
    )
    # …

You can use a DetailView to render a single Country , so:您可以使用DetailView来呈现单个Country ,因此:

from django.views.generic.detail import DetailView

class CountryDetailView(DetailView):
    template_name = 'country_detail.html'
    model = Country
    context_object_name = 'country'

In the urls, you can thus register this view under the name cities with a slug field:在 urls 中,您可以在带有 slug 字段的名称cities下注册此视图:

# app/urls.py

from django.urls import path

from . import views

app_name='city'

urlpatterns = [
    # …,
    path(
        'country/<slug:slug>',
        views.CountryDetailView.as_view(),
        name='cities'
    ),
]

In the template, you can then access the relation in reverse:在模板中,您可以反向访问该关系:

<!-- country_detail.html -->

{{ country }}

{% for city in country.cities.all %}
    {{ city }}
{% endfor %}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM