Django rest framework 如何使用rest框架在django上编写通用CRUD服务?

Django rest framework 如何使用rest框架在django上编写通用CRUD服务?,django-rest-framework,Django Rest Framework,我是django的新手,在尝试编写一个简单的服务时遇到了几个问题 我想做什么 我打算使用rest框架库为我的模型编写一个通用crud服务。 我不想为我所有的模型编写序列化程序和视图,并试图优化代码和学习一些有用的东西 我的型号 让我们假设我有一个抽象的BaseBusinessObject class BaseBusinessObject(models.Model): CreatedAt = models.DateField() UpdatedAt = models.DateFi

我是django的新手,在尝试编写一个简单的服务时遇到了几个问题

  • 我想做什么

    我打算使用rest框架库为我的模型编写一个通用crud服务。
    我不想为我所有的模型编写序列化程序和视图,并试图优化代码和学习一些有用的东西

  • 我的型号

    让我们假设我有一个抽象的BaseBusinessObject

    class BaseBusinessObject(models.Model):
    
        CreatedAt = models.DateField()
        UpdatedAt = models.DateField()
    
        class Meta:
            abstract = True
    
    
    我还有很多具体的类,它们是从基本类继承的:

    class Product(BaseBusinessObject):
         Description: models.TextField()
         Type: models.CharField()
    
    ....
    
    class Company(BaseBusinessObject):
        Title: models.CharField()
    
    ....
    
    class Person(BaseBusinessObject):
        Name: models.CharField()
    
    等等

  • 我想要什么

    我已经发现,使用rest框架,我可以创建序列化程序和视图,然后为url…/Product…/Company…/Person注册路由器。但是如果我有1000门课呢?这太无聊了

    A.如何为子对象动态指定url?我不想硬编码方法,我正在寻找解决方案…类似于这样: …/api/Entities/ClassName

    B.然后如何在django rest框架中使用动态创建的URL

    router.register('persons', PersonViewSet)
    
    如何以更通用的方式编写

    router.register('<ClassName>', <GenericViewSet>)
    
  • 但正如我所说,我有很多课程。我怎样才能用更一般的方式来写呢

    我试图为抽象类创建一个视图集,但在查询抽象对象时遇到了一些问题

    是否有可能为抽象类创建这样的服务,然后其所有子类都简单(或不简单)继承CRUD方法

    也许我应该尝试为序列化程序和视图集编写一个工厂


    我可以实施哪些可能的解决方案来解决我的问题?

    我建议使用查询参数而不是路径参数,然后您只需注册一个URL并处理请求的各种元素,并将其正确地路由到服务器端

    经过两天的周游,我终于找到了解决办法。可能是其他人会面临一些问题,所以我试图解释我已经做了什么

    首先,我在django项目中创建一个“基本”应用程序,并将其添加到settings.py。然后我在models.py中创建了一个抽象类:

    class BaseCrudEntity(models.Model):
        pass
        class Meta:
            abstract = True
    
    我想为所有“业务”类的CRUD操作编写一个通用服务。 问题是我不想为它们编写序列化程序和视图——我想动态地“动态”创建它们。我决定也使用django rest框架,因为我不打算再次创建bycicle。 我决定从那个抽象类继承我所有的“业务”类,并为所有可能的“家族”编写一个服务

    所以我必须创建一个负责创建VeiwSet的结构。 以下是my view.py:

    class BaseCrudViewSetFabric():
    
        @classmethod
        def CreateViewSet(self, _context):
            classname = _context.__name__ + 'ViewSet'
            return type(classname, (viewsets.ModelViewSet,), {
                'queryset':_context.objects.all(),
                'serializer_class':BaseCrudSerializerFabric.CreateSrializer(_context)
            })
            pass
    
    这里是描述我的模型的具体类的上下文变量。 如您所见,此函数基于我的上下文创建一个具体的视图集。在它内部,称为序列化器结构。 下面是my serializers.py的代码:

    class BaseCrudSerializerFabric():
    
        @classmethod
        def CreateSrializer(self, _context):
            classname = _context.__name__
            _Meta = type('Meta', (), {'model':_context,'fields':'__all__'})
            _crudserializer = type(
                classname,
                (serializers.ModelSerializer,),
                {'Meta': _Meta}        
            )
            return _crudserializer
    
    此外,我必须为动态路由编写一个服务——我不想硬编码我的URL。 以下是核心项目的ursl.py示例:

    from base.urls import router
    url(r'^api/v1/', include(router.urls))
    
    并从base/url.py:

    from rest_framework.routers import DefaultRouter, SimpleRouter
    from base.models.BaseCrudEntity import BaseCrudEntity
    from base.views.basecrud_view import BaseCrudViewSetFabric
    
    class CustomRouter(SimpleRouter):
    
        def RoutRegister(self):
            childs = getChilds(BaseCrudEntity)
            #print(childs)
            for ch in childs:
                if (ch._meta.abstract == False):
                    #print(ch.__name__)
                    prefix = ch.__name__
                    self.register(prefix, BaseCrudViewSetFabric.CreateViewSet(ch))
            return(self)
        pass
    
    router = CustomRouter()
    router.RoutRegister()
    
    最后,我只是创建了一些具体的模型:

    from django.db import models
    from base.models.BaseCrudEntity import BaseCrudEntity
    
    class Person(BaseCrudEntity):
    
        Name = models.CharField(max_length = 255)
        Surname = models.CharField(max_length = 255)
        Patronymic = models.CharField(max_length = 255, null = True)
        DateOfBirth = models.DateField(null = True)
        #slug = models.SlugField(default = 'hui', editable = False)
    
        def __str__(self):
            return "{} {} {}".format (self.Surname, self.Name, self.Patronymic)
    
    就这些。
    当应用程序启动时,它会注册一个路由并创建序列化程序和视图集,这样Django-Rest框架提供的所有CRUD操作也会提供。

    @Valerity Checkout此网站可能会帮助您,谢谢,但它不适合您。我已经阅读了关于DRF的实际文档。问题是我如何将其用于抽象模型,然后用于所有子类,或者有另一种可能的解决方案。需要更多关于预期输入和输出的信息我无法准确地告诉你我预期的是什么,因为我对Django很陌生。但是我想为我的业务对象的CRUD操作编写一个服务。让我们假设它们是从抽象类继承的。我应该怎样用一般的方法来做呢?我试着在我的问题中解释它。我不是以英语为母语的人。我是否清楚地解释了我自己?我想了想,但是如果你有很多类似方法的类,这就太无聊了。我已经做了一个关于动态URL的:1。我决定为所有这样的类创建一个BaseCrudential并继承它2。我定义了一个返回一组子类3的函数。然后我编写了一个自定义路由器,并使用
    self.register(prefix,GenericViewSet)
    注册了所有路由,因此我有大量类似于……实体的URL/
    from django.db import models
    from base.models.BaseCrudEntity import BaseCrudEntity
    
    class Person(BaseCrudEntity):
    
        Name = models.CharField(max_length = 255)
        Surname = models.CharField(max_length = 255)
        Patronymic = models.CharField(max_length = 255, null = True)
        DateOfBirth = models.DateField(null = True)
        #slug = models.SlugField(default = 'hui', editable = False)
    
        def __str__(self):
            return "{} {} {}".format (self.Surname, self.Name, self.Patronymic)