python - 带有 filter() 和 order_by() 的查询集 distinct() 不起作用

标签 python django django-models sqlite django-forms

我正在使用以下模型和表单来构建两个下拉菜单。城市菜单取决于国家菜单。现在我的代码正确地进行了过滤和排序。但是,distinct() 不起作用。我已经尝试了一段时间的查询排序,但它仍然不起作用。我该如何解决这个问题?

模型.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

表单.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})

最佳答案

当数据库服务器运行有序的不同查询时,它将:

  1. 从存储中收集匹配的行,根据 WHERE 子句检查它们。
  2. 根据 ORDER BY 子句排序。
  3. 发出每一行,其中该行与前一个(有序的)发出的行 DISTINCT

由于您通过不将任何字段名称传递给 order_by() 来显式禁用排序,因此数据库可以按照它选择的任何顺序(通常在他们从存储中检索的顺序)。

DISTINCT 过滤不适用于整个结果集,它仅适用于前面发出的行并且由于您的结果是以未定义的(随机)顺序发出,DISTINCT 不太可能过滤任何结果。

您必须通过在查询的 order_by(*fields) 部分指定字段名称来对结果进行相应排序。

关于python - 带有 filter() 和 order_by() 的查询集 distinct() 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49162937/

相关文章:

javascript - 如何从Google自定义搜索下载搜索结果?

Pythonic 和紧凑的方式来比较字典中的键

javascript - 填充数据库字段 Django

Django Nginx 浏览器缓存配置

python - 类型为 'f' 的对象的未知格式代码 'unicode'

django - 在 Django Rest Framework 中接收 Base64 编码的图像并保存到 ImageField

database - Django 中唯一的 BooleanField 值?

python - 如何使用 django 通用基于类的 View 添加最喜欢的文章标记系统?

python - 如何使用 Content-MD5 将对象放入 s3

模型创建的 Django 默认条目