【问题标题】:Django get class from stringDjango从字符串中获取类
【发布时间】:2016-03-05 03:52:15
【问题描述】:

我正在寻找一种在 Python 中通过类名来实例化类的通用方式,其方式与在 Java 中的实现方式类似,而无需在 IF..ELIF 条件中显式指定类名。

这是因为我有几个不同的模型和序列化程序,并希望通过 HTTP 请求中的参数使它们可寻址。是为了增强松耦合和模块化。

例如https://www.domain.com/myapp/sampledata.json?model=<modelname> 应该得到<modelname><modelname>Serializer 类。

自 Django 1.7 https://docs.djangoproject.com/en/1.7/ref/models/queries/ 以来对此进行了一些更改,在 get_model 用于类似目的之前。

从 Django 1.7 开始,django.db.models.loading 已被弃用(将 在 1.9 中删除)以支持新的应用程序加载系统。

警告:

RemovedInDjango19警告:django.db.models.loading 中的实用程序 已弃用,取而代之的是新的应用程序加载系统。
返回 f(*args, **kwds)

下面的代码应该如何修改才能从字符串中获取类?

views.py

from myapp.models import Samplemodel, Simplemodel1, Simplemodel2
from myapp.serializers import SamplemodelSerializer, Simplemodel1Serializer, Simplemodel2Serializer
from django.db.models.loading import get_model # deprecated
from myapp.jsonp_decorator import json_response

@json_response
def sampledata(request):

    model = request.GET.get('model','Samplemodel')

    if model=='Samplemodel':
        modelName = "Samplemodel"
        serializer = SamplemodelSerializer
    elif model=='Simplemodel1':
        modelName = "Simplemodel1"
        serializer = Simplemodel1Serializer
    elif model=='Simplemodel2':
        modelName = "Simplemodel2"
        serializer = Simplemodel2Serializer

    return serializer(get_model("myapp",modelName).objects.all(), many=True)  

【问题讨论】:

    标签: generics django-models generic-programming django-1.8 django-serializer


    【解决方案1】:

    你可以使用getattr:

    import my_serializers
    
    serializer_class = getattr(my_serializers, 'SimpleSerializer')
    serializer = serializer_class()
    

    【讨论】:

    • 似乎可以使用属性,我需要与模型和序列化程序类似的东西
    • 它也适用于模块内的类。它们是模块的属性。
    • 你说得对,它工作得很好,我会在这里发布更新的代码。
    【解决方案2】:

    对于 Django 3+ 获取模型实例的通用方法:

    def get_data_instance(model_name):
        """
        Try to find application with name "data" with specific "model_name"
        :param model_name: the name of the class
        :return: model instance or None
        """
    
        try:
            app_config = apps.get_app_config('data')
            return app_config.get_model(model_name)
        except LookupError:
            pass
    
        return None
    

    【讨论】:

      【解决方案3】:

      在这种情况下允许动态类加载的最佳方法是:

      from myapp import models
      from myapp import serializers
      from myapp.jsonp_decorator import json_response
      
      @json_response
      def sampledata(request):
      
          model = request.GET.get('model','Samplemodel')
          serializer_class = getattr(serializers, model+"Serializer")
          return serializer_class(getattr(models,modelName).objects.all(), many=True)
      

      【讨论】:

        猜你喜欢
        • 2011-06-20
        • 1970-01-01
        • 2011-01-25
        • 2013-07-01
        • 2012-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-03
        相关资源
        最近更新 更多