首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >大多数Pythonic/Django方法在运行时动态加载客户端库

大多数Pythonic/Django方法在运行时动态加载客户端库
EN

Stack Overflow用户
提问于 2019-07-30 07:40:43
回答 2查看 164关注 0票数 0

我正在编写Django应用程序,在这个应用程序中,我们将拥有多个调用第三方API的客户端库。当调用不同的端点时,我们希望能够确定在运行时加载哪个客户端库。我正试图确定最能做到这一点的Django/Pythonic方法

当前的思想是将类名存储在模型字段中,在视图中查询模型,并将类名传递给服务工厂,后者实例化相关服务并进行查询。我还考虑过编写一个使用反射查询类名的模型方法

例如,假设我们有一个名为Exchange的模型,它具有一个id、一个名称,并存储客户端名称。

代码语言:javascript
运行
复制
class Exchange(models.Model):
    exchange_name = models.CharField(max_length=255)
    client_name = models.CharField(max_length=255)

    def __str__(self):
        return self.exchange_name

那么在“视图”中,我们可能会看到这样的内容:

代码语言:javascript
运行
复制
from rest_framework.views import APIView
from MyProject.trades.models import Exchange
from django.http import Http404
from MyProject.services import *


class GetLatestPrice(APIView):

    def get_object(self, pk):
        try:
            exchange = Exchange.objects.get(pk=pk)
        except Exchange.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        exchange = self.get_objectt(pk)
        service = service_factory.get_service(exchange.client_name)
        latest_price = service.get_latest_price()
        serializer = PriceSerializer(latest_price)
        return Response(serializer.data)

这个语法可能并不完美,但还没有经过测试。但我们的想法是也许我们

代码语言:javascript
运行
复制
ExchangeA - client1 
ExchangeB - client2
ExchangeC - client3

对于每个客户端,我们都有一个服务类,它们都是从同一个抽象库继承的。每个服务都有相同的覆盖。这样,当您调用/api/get_latest_price时,您将Exchange id作为查询param传递,并且代码加载任何与服务和客户端库相关的服务。这样我们就可以轻松地向系统添加新类型,具有一致和小的视图,并将业务逻辑解耦。这是一个可接受的,可伸缩的pythonic方法吗?还是有更好的解决方案?本质上,问题是在django中实现多态性,并将域模型与数据模型分离。这必须是一个解决的问题,所以我很好奇其他人可能会这样做。我知道像这样调用第三方API是不寻常的,但是由于我们被迫这样做,我想以尽可能干净、最可伸缩的方式来实现它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-30 08:54:49

TL;DR

没有银弹。

更有用的答案:

没有通用和方便的方法来解决你的问题。解决方案可能因客户端库和第三方API的实现而有很大差异。如果它们都是相似的,你可以使用你的方法,你会没事的。如果API有一些不同,例如,一个API没有端点来获得最新的价格,那么您需要找到一些解决办法。如果API在工作流方面有很大差异,您需要找到完全不同的方法,例如,如果一个API可以立即返回报告,而另一些API在5分钟后通过回调返回报表,则需要找到解决办法。

因此,我能给您的一个真正的建议是检查第三方API之间的差异,并更多地关注您自己的项目的最高抽象的设计,这将使用低级别的客户机库。尽量减少第三方之间的差异对您的项目的影响。

票数 1
EN

Stack Overflow用户

发布于 2019-07-30 12:04:19

这里有类似的情况(以及其他一些密切相关的情况),并使用这种模式:将"service“类的名称存储在模型中,并使用一些注册表(您的"service_factory")来获取该类。It JustWorks(tm),没有人(来自不同的开发人员加入--并最终离开)抱怨过这个设计,也没有提出过任何更好的解决方案,到目前为止,我们遇到的唯一的小问题就是处理仍然从数据库中引用的“已停止的”服务(这也确实不是火箭科学)。

FWIW,这主要是“策略”设计模式的一个变体,我真的无法想象有一个更好的(“更好”=“更简单、更有效和更易于维护”)解决方案。

编辑

请注意,我的上述答案假设Exchange有其他在您的问题中没有提到的响应--否则,正如Alexandr所说的,这个模型似乎相当无用;)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57266619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档