简体   繁体   English

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

[英]Is there any way to use any user-defined Python method in the Case-When query of Django ORM?

I have defined a class along with its necessary methods, which is as following.我已经定义了一个类及其必要的方法,如下所示。

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)]

Here, in the retrieve_location_data method, I have tried to use a user-defined ( prepare_location_hotlink ) Python method in Case query to retrieve all of the location data as hotlinked.在这里,在retrieve_location_data方法中,我尝试在Case查询中使用用户定义的prepare_location_hotlink )Python 方法来检索所有位置数据作为热链接。 It seems not working in the above way.似乎不能以上述方式工作。 But I need to use the user-defined python method in the Case query anyway, as it retrieves and prepares data much faster.但无论如何我都需要在Case查询中使用用户定义的python 方法,因为它检索和准备数据的速度要快得多。 I already researched and read the Django documentation, but unfortunately, I could not find any solution for this case.我已经研究并阅读了Django文档,但不幸的是,我找不到针对这种情况的任何解决方案。

Is there any proper and accurate way on how to use any user-defined Python method in the Case query of Django ORM ?关于如何在Django ORMCase查询中使用任何用户定义的Python 方法,是否有任何正确和准确的方法?

Is there any proper and accurate way on how to use any user-defined Python method in the Case query of Django ORM?关于如何在Django ORM的Case查询中使用任何用户定义的Python方法,是否有任何正确和准确的方法?

No , since the database does not know anything about Django.,因为数据库对 Django 一无所知。 It is just a program that inteprets queries to store/retrieve/aggregate data.它只是一个解释查询以存储/检索/聚合数据的程序。 But nevertheless, it is not a good idea to let the database do complex processing anyway.但是无论如何,让数据库进行复杂的处理并不是一个好主意。 Databases are not designed for this.数据库不是为此而设计的。

You can simply perform the operations in the list comprehension:您可以简单地执行列表理解中的操作:

from itertools import starmap

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):
        if long 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')
        )

You can use the Concat function to concatenate your string at database level, nevertheless, in this situation I would go for @Willem Van Onsem answer which is more readable and maintainable.您可以使用Concat函数在数据库级别连接字符串,但是,在这种情况下,我会选择更具可读性和可维护性的 @Willem Van Onsem 答案。

You can also wrap you queryset with list() to make it a list.您还可以使用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))

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

相关问题 有没有办法让用户定义的函数出现在完全不同的命名空间中? - Is there any way to make user-defined functions appear in a totally different namespace? Django ORM查询中如何使用长度法 - How to use the length method in Django ORM Query 使用Python类中的方法作为PySpark用户定义函数 - Using a method from a Python class as a PySpark user-defined function 使用 numpy 生成带有 case-when 条件的随机数据 - Use numpy to generate random data with case-when condition 在Python中的用户定义类中将用户定义的异常子类化 - Subclassing a user-defined exception in a user-defined class in Python 如何在Python用户定义函数中使用数组/向量? - How to use arrays/vectors in a Python user-defined function? 有没有办法使用 Django ORM 进行手动连接? - Is there any way to make a manual join using Django ORM? 有什么方法可以在更改代码时使用 django shell 而无需重新启动 - Is there any way to use django shell without restarting when change code Django:未捕获用户定义的异常 - Django: User-defined exception not being caught Django中用户定义的派生数据 - User-defined derived data in Django
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM