Django queryset未返回不同的值
我有一个查询,由于某种原因,即使我指定了distinct,也没有返回distinct值,我认为这可能是因为only,所以我删除了它,但列表仍然是一样的Django queryset未返回不同的值,django,sqlite,django-queryset,Django,Sqlite,Django Queryset,我有一个查询,由于某种原因,即使我指定了distinct,也没有返回distinct值,我认为这可能是因为only,所以我删除了它,但列表仍然是一样的 circuit_providers = CircuitInfoData.objects.only('provider').values('provider').distinct() 我只想要一个unqiue提供者的列表 model.py from __future__ import unicode_literals from django.d
circuit_providers = CircuitInfoData.objects.only('provider').values('provider').distinct()
我只想要一个unqiue提供者的列表
model.py
from __future__ import unicode_literals
from django.db import models
import string
import random
import time
import os
# Create your models here.
from service.models import ServiceContacts
def site_photos_path(instance, filename):
file ,extension = os.path.splitext(filename)
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
chars=string.ascii_uppercase + string.digits
random_string = ''.join(random.choice(chars) for _ in range(6))
filename = '%s-%s%s' % (random_string,time.strftime("%d-%m-%H-%M-%S"),extension)
return 'site_photos/{0}'.format(filename)
def service_upload_path(instance, filename):
file ,extension = os.path.splitext(filename)
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
chars=string.ascii_uppercase + string.digits
random_string = ''.join(random.choice(chars) for _ in range(6))
filename = '%s-%s%s' % (random_string,time.strftime("%d-%m-%H-%M-%S"),extension)
return 'service_files/{0}'.format(filename)
def site_files_path(instance, filename):
file ,extension = os.path.splitext(filename)
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
chars=string.ascii_uppercase + string.digits
random_string = ''.join(random.choice(chars) for _ in range(6))
filename = '%s-%s%s' % (random_string,time.strftime("%d-%m-%H-%M-%S"),extension)
return 'site_files/{0}'.format(filename)
provider_choices = (
('KCOM','KCOM'),
('BT','BT'),
('EE','EE'),
('THREE','THREE'),
)
circuit_choices = (
('DSL','DSL'),
('VDSL','VDSL'),
('MPLS','MPLS'),
('4G','4G'),
('Internet Leased Line','Internet Leased Line'),
)
subnet_mask_choices = (
('/16','/16'),
('/24','/24'),
('/25','/25'),
('/26','/26'),
('/27','/27'),
('/28','/28'),
('/29','/29'),
('/30','/30'),
('/31','/31'),
)
class ShowroomConfigData(models.Model):
location = models.CharField(max_length=50)
subnet = models.GenericIPAddressField(protocol='IPv4')
r1_loopback_ip = models.GenericIPAddressField(protocol='IPv4',verbose_name="R1 Loopback IP")
r2_loopback_ip = models.GenericIPAddressField(protocol='IPv4',verbose_name="R2 Loopback IP")
opening_date = models.DateField(verbose_name="Showroom opening date")
last_hw_refresh_date = models.DateField(verbose_name="Date of latest hardware refresh")
is_showroom = models.BooleanField(default=True,verbose_name="Is this site a showroom?")
class Meta:
verbose_name = "Showroom Data"
verbose_name_plural = "Showroom Data"
ordering = ('location',)
def __unicode__(self):
return self.location
class MajorSiteInfoData(models.Model):
location = models.CharField(max_length=200)
major_subnet = models.GenericIPAddressField(protocol='IPv4',verbose_name="Major Site Subnet")
routed_subnet = models.GenericIPAddressField(protocol='IPv4',verbose_name="Routed Link Subnet")
bgp_as = models.CharField(max_length=6,verbose_name="BGP AS Number")
class Meta:
verbose_name = "Major Site Data"
verbose_name_plural = "Major Site Data"
def __unicode__(self):
return self.location
class CircuitInfoData(models.Model):
showroom_config_data = models.ForeignKey(ShowroomConfigData,verbose_name="Install Showroom")
major_site_info = models.ForeignKey(MajorSiteInfoData,verbose_name="Install Site")
circuit_type = models.CharField(max_length=100,choices=circuit_choices)
circuit_speed = models.IntegerField(blank=True)
circuit_bearer = models.IntegerField(blank=True)
provider = models.CharField(max_length=200,choices=provider_choices)
ref_no = models.CharField(max_length=200,verbose_name="Reference No")
class Meta:
verbose_name = "Circuit Data"
verbose_name_plural = "Circuit Data"
ordering = ('showroom_config_data__location','circuit_speed')
def __unicode__(self):
return '%s | %s | %s | %s | %s' % (self.showroom_config_data.location,self.major_site_info.location, self.provider, self.service_type, self.ref_no)
我注意到的一件事是,当我像上面那样在shell中打印项目时
#### with def __unicode__(self): #####
>>> from networks.models import CircuitInfoData
>>> d = CircuitInfoData.objects.only('provider').distinct()
>>> for i in d:
... print i
...
Location1 | Showroom | BT | DSL | N/A
Location2 | Showroom | BT | MPLS | XXXX
Location2 | Showroom | KCOM | MPLS | XXXX
Location3 | Showroom | BT | MPLS | XXXX
Location3 | Showroom | BT | DSL | N/A
Location4 | Showroom | KCOM | MPLS | XXXXX
...
#### with out def __unicode__(self): #####
>>> from networks.models import CircuitInfoData
>>> d = CircuitInfoData.objects.only('provider').distinct()
>>> for i in d:
... print i
...
CircuitInfoData_Deferred_circuit_bearer_circuit_cfb3d62ef325a6acfc8ddcb43c8ae1c6 object
CircuitInfoData_Deferred_circuit_bearer_circuit_cfb3d62ef325a6acfc8ddcb43c8ae1c6 object
CircuitInfoData_Deferred_circuit_bearer_circuit_cfb3d62ef325a6acfc8ddcb43c8ae1c6 object
CircuitInfoData_Deferred_circuit_bearer_circuit_cfb3d62ef325a6acfc8ddcb43c8ae1c6 object
CircuitInfoData_Deferred_circuit_bearer_circuit_cfb3d62ef325a6acfc8ddcb43c8ae1c6 object
CircuitInfoData_Deferred_circuit_bearer_circuit_cfb3d62ef325a6acfc8ddcb43c8ae1c6 object
...
#### with either ####
>>> for i in d:
... print i.provider
...
BT
BT
KCOM
BT
BT
KCOM
...
该文件的内容如下:
返回在其SQL查询中使用SELECT DISTINCT的新查询集。
这将从查询结果中消除重复的行
默认情况下,查询集不会消除重复的行。实际上,,
这很少是一个问题,因为诸如
Blog.objects.all()不会引入重复结果的可能性
排
Distinct为您提供了不同的行,但您只查看记录中的一个字段,并且在该字段中可以复制项,除非对其具有唯一约束。在这种情况下,你没有
如果您碰巧正在使用postgresql,您可以这样做
CircuitInfoData.objects.distinct('provider')
实现你的目标
更新:
由于您在评论中提到使用sqlite,所以请使用此解决方案
CircuitInfoData.objects.values('provider').distinct()
这将起作用,因为现在每行只有一列。结果查询将类似于
SELECT DISTINCT "someapp_circuitinfodata"."name" FROM "someapp_circuitinfodata"
更新2:
请注意,您已经覆盖了\uuuuuunicode\uuuuu
函数
def __unicode__(self):
return '%s | %s | %s | %s | %s' %
(self.showroom_config_data.location,self.major_site_info.location,
self.provider, self.service_type, self.ref_no)
您指的是相关模型中的字段。这将是非常昂贵的(除非您使用select\u related
)。还要注意的是,如果您迭代查询集并出于调试目的使用print,它会给您带来误导性的结果(因为您看到的是\uuuuuunicode\uuuuu
,一个相当复杂的函数的输出)的文档
返回在其SQL查询中使用SELECT DISTINCT的新查询集。
这将从查询结果中消除重复的行
默认情况下,查询集不会消除重复的行。实际上,,
这很少是一个问题,因为诸如
Blog.objects.all()不会引入重复结果的可能性
排
Distinct为您提供了不同的行,但您只查看记录中的一个字段,并且在该字段中可以复制项,除非对其具有唯一约束。在这种情况下,你没有
如果您碰巧正在使用postgresql,您可以这样做
CircuitInfoData.objects.distinct('provider')
实现你的目标
更新:
由于您在评论中提到使用sqlite,所以请使用此解决方案
CircuitInfoData.objects.values('provider').distinct()
这将起作用,因为现在每行只有一列。结果查询将类似于
SELECT DISTINCT "someapp_circuitinfodata"."name" FROM "someapp_circuitinfodata"
更新2:
请注意,您已经覆盖了\uuuuuunicode\uuuuu
函数
def __unicode__(self):
return '%s | %s | %s | %s | %s' %
(self.showroom_config_data.location,self.major_site_info.location,
self.provider, self.service_type, self.ref_no)
您指的是相关模型中的字段。这将是非常昂贵的(除非您使用
select\u related
)。还要注意的是,如果您迭代查询集并出于调试目的使用print,它会给您带来误导性的结果(因为您看到的是\uuuuuuunicode\uuuuu
,一个相当复杂的函数的输出)您可以使用print circuit\u providers.query
来显示原始查询并查看sql语句的情况,可能在数据库外壳中运行原始sql并进行验证。@ShangWang我添加了输出,它看起来甚至不像是添加了group by语句……您使用哪个数据库后端Model.values('field_name').distinct()
适用于PostgreSQL。其他后端可能存在差异。哪一个版本的Django?这看起来像是一个bug.sqlite3,django 1.9SQLite很棒,但django中有相当多的数据库功能只在PostgreSQL中可用。我的印象是,psql后端的bug也更少。可能是因为这是大多数高级站点在生产中使用的,所以更多的精力用于报告和修复问题。您可以使用打印电路\u提供程序。query
显示原始查询并查看sql语句的情况,可以在数据库外壳中运行原始sql并验证它。@ShangWang我添加了输出,它甚至看起来不像是添加了一个GROUPBY语句……您使用哪个数据库后端Model.values('field_name').distinct()
适用于PostgreSQL。其他后端可能存在差异。哪一个版本的Django?这看起来像是一个bug.sqlite3,django 1.9SQLite很棒,但django中有相当多的数据库功能只在PostgreSQL中可用。我的印象是,psql后端的bug也更少。可能是因为这是大多数高级站点在生产中使用的,所以更多的精力放在报告和修复问题上。这给了我一个未实现的错误:此数据库后台不支持DISTINCT ON字段只有psql支持DISTINCT
的参数。因此,对于其他后端,您可以这样做CircuitInfoData.objects.values('provider').distinct()
,但是,在本例中,这似乎是错误的。@HåkenLid我在发布该答案时犯了复制粘贴错误。正确的格式确实与您在评论中发布的格式相同。我刚刚通过测试再次确认了这一点。请查看最新更新,显示它不再工作。这给了我未实现的错误:此数据库后台不支持字段上的DISTINCT仅psql支持DISTINCT的参数。因此,对于其他后端,您可以这样做CircuitInfoData.objects.values('provider').distinct()
,但是,在本例中,这似乎是错误的。@HåkenLid我在发布该答案时犯了复制粘贴错误。正确的格式确实与您在评论中发布的格式相同。我刚刚通过测试再次确认。请查看最新更新,显示它不再工作