我使用以下模型和表单来构建两个下拉菜单。 “城市”菜单取决于“国家/地区”菜单。现在我的代码正确地进行过滤和排序。但是,distinct()不起作用。我已经玩了一段时间的查询排序,它仍然无法正常工作。我该如何解决这个问题?
models.py
from django.db import models
class Country(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class City(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Person(models.Model):
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
forms.py
from django import forms
from .models import Person, City
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('country', 'city')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['city'].queryset = City.objects.none()
if 'country' in self.data:
try:
country_id = int(self.data.get('country'))
self.fields['city'].queryset = City.objects.filter(country_id=\
country_id).order_by().distinct()
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty City queryset
elif self.instance.pk:
self.fields['city'].queryset = self.instance.country.city_set.order_by('name')
views.py
from django.shortcuts import render
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy
from .models import Person, City
from .forms import PersonForm
class PersonListView(ListView):
model = Person
context_object_name = 'people'
class PersonCreateView(CreateView):
model = Person
form_class = PersonForm
success_url = reverse_lazy('person_changelist')
class PersonUpdateView(UpdateView):
model = Person
form_class = PersonForm
success_url = reverse_lazy('person_changelist')
def load_cities(request):
country_id = request.GET.get('country')
cities = City.objects.filter(country_id=country_id).order_by('name')
return render(request, 'hr/city_dropdown_list_options.html', {'cities': cities})
答案 0 :(得分:1)
当数据库服务器运行有序的不同查询时,它将:
WHERE
子句检查它们。ORDER BY
条款进行排序。DISTINCT
的每一行。由于您没有将任何字段名称传递给order_by()
,因此您已明确禁用排序,因此数据库可以按其选择的顺序(通常按照从存储中检索的顺序)发出行)。
DISTINCT
过滤并不适用于整个结果集,它仅对前面发出的行应用。并且由于您的结果正在以未定义(随机)顺序发出,DISTINCT
不可能过滤任何结果。
您必须通过在查询的order_by(*fields)
部分指定字段名称来相应地订购结果。