在Django ORM的Case When查询中,有没有办法使用任何用户定义的Python方法



我定义了一个类及其必要的方法,如下所示。

class Location(models.Model):
latitude = models.DecimalField(max_digits=20, decimal_places=8, default=Decimal("0.00"), null=True)
longitude = models.DecimalField(max_digits=20, decimal_places=8, default=Decimal("0.00"), null=True)
@staticmethod
def prepare_location_hotlink(latitude=None, longitude=None):
returm mark_safe(s="<a class='inline-link' href='https://maps.google.com/maps?z=17&q={lat},{lng}' target='_blank'>{lat}, {lng}</a>".format(lat=latitude, lng=longitude))
@classmethod
def retrieve_location_data(cls):
annotated_case_query = {
"location": Case(
When(Q(location__isnull=False, longitude__isnull=False),
then=cls.prepare_location_hotlink(latitude=F("latitude"), longitude=F("longitude"))
), default=Value("Not Available"), output_field=CharField()
)
}
return [loc for loc in cls.objects.annotate(**annotated_case_query).values_list("location", flat=True)]

这里,在retrieve_location_data方法中,我尝试在Case查询中使用用户定义的(prepare_location_hotlink(Python方法来检索作为热链接的所有位置数据。它似乎没有以上述方式工作。但无论如何,我都需要在Case查询中使用用户定义的python方法,因为它检索和准备数据的速度要快得多。我已经研究并阅读了Django文档,但不幸的是,我找不到任何解决方案。

关于如何在Django ORMCase查询中使用任何用户定义的Python方法,是否有任何正确和准确的方法?

在Django ORM的Case查询中,如何使用任何用户定义的Python方法,有什么正确准确的方法吗?

,因为数据库对Django一无所知。它只是一个集成查询以存储/检索/聚合数据的程序。但是,无论如何,让数据库进行复杂的处理都不是一个好主意。数据库不是为此而设计的。

您可以简单地执行列表理解中的操作:

from itertools importstarmap
class Location(models.Model):
latitude = models.DecimalField(
max_digits=20,
decimal_places=8,
default=Decimal('0.00'),
null=True
)
longitude = models.DecimalField(
max_digits=20,
decimal_places=8,
default=Decimal('0.00'),
null=True
)
@staticmethod
def prepare_location_hotlink(long=None, lat=None):
iflong is None and lat is None:
return 'Not Available'
return mark_safe(f"<a class='inline-link' href='https://maps.google.com/maps?z=17&q={lat},{lng}' target='_blank'>{lat}, {lng}</a>")
@classmethod
def retrieve_location_data(cls):
return list(starmap(
Location.prepare_location_hotlink,
cls.objects.values_list('longitude', 'latitude')
)

您可以使用Concat函数在数据库级别连接字符串,不过,在这种情况下,我会选择更可读、更可维护的@Willem Van Onsem答案。

您也可以用list()包装查询集,使其成为列表。

from django.db.models import Q, Case, When, Value, F
from django.db.models.functions import Concat
annotated_case_query = {
"location": Case(
When(Q(location__isnull=False, longitude__isnull=False),
then=Concat(Value("<a class='inline-link' href='https://maps.google.com/maps?z=17&q="), F("latitude"), Value(","), F("longitude"), Value("' target='_blank'>"), F("latitude"), Value(", "), F("longitude"), Value('</a>'))
), default=Value("Not Available"), output_field=CharField()
)
}
return list(cls.objects.annotate(**annotated_case_query).values_list("location", flat=True))

最新更新