Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django API设计最佳实践:使用json\u build\u对象将SQL SELECT查询构造为类似json的结构是否好_Django_Rest_Django Rest Framework - Fatal编程技术网

Django API设计最佳实践:使用json\u build\u对象将SQL SELECT查询构造为类似json的结构是否好

Django API设计最佳实践:使用json\u build\u对象将SQL SELECT查询构造为类似json的结构是否好,django,rest,django-rest-framework,Django,Rest,Django Rest Framework,我正在开发一个基于web的应用程序,它实现以下功能: PostgreSQL RDBMS非ORM数据库 Django Rest框架,用于在后端设计和处理数据序列化程序和API请求 对于GET方法,将sqlselect查询设计为类似json的结构 使用json_构建_对象 在数据库中 person(personid, fullname, cityid) city(cityid, cityname, countryid) country(countryid, countryname) 在序列化程序中

我正在开发一个基于web的应用程序,它实现以下功能:

  • PostgreSQL RDBMS非ORM数据库
  • Django Rest框架,用于在后端设计和处理数据序列化程序和API请求
  • 对于GET方法,将sqlselect查询设计为类似json的结构 使用json_构建_对象
  • 在数据库中

    person(personid, fullname, cityid)
    city(cityid, cityname, countryid)
    country(countryid, countryname)
    
    在序列化程序中

    class CountrySerializer(serializers.Serializer):
     id=serializers.IntegerField()
     name=serializers.CharField()
    
    class CitySerializer(serializers.Serializer):
     id=IntegerField()
     name=CharField()
     country=CountrySerializer()
    
    class PersonSerializer(serializers.Serializer):
     id=IntegerField()
     person=CharField()
     city=CitySerializer()
    
    在API视图中

    from .custom_utils import raw_sql_select
    
    class APIView_Person(generics.GenericAPIView):
      serializer_class = PersonSerializer
      permission_classes = (IsAuthenticatedOrReadOnly,)
      def get_queryset(self):
       query=("""
        SELECT
         p.personid as id,
         p.fullname as person,
         json_build_object(
          'id',ct.cityid,
          'name',ct.cityname,
          'country',json_build_object(
            'id',cntry.countryid,
            'name',cntry.countryname
           )
         ) AS city
         FROM persons p
         JOIN city ct ON ct.cityid=p.cityid
         JOIN country cntry ON cntry.countryid=ct.countryid
       """)
       return raw_sql_select(query, "db_connection")
    
      def get(self, request):
       rows = [
        {
          "id": col.id,
          "person": col.person,
          "city": col.city
        } for col in self.get_queryset()[1]
       ]
       results = PersonSerializer(rows, many=True).data
       return Response(results or [])
    
    在前端

    const [state, setState] = useState({
     personList: []
    })
    
    useEffect(()=>{
      fetch('/api/persons/', {method: 'GET', headers:{'Content-Type':'application/json'}})
      .then(res=>res.json())
      .then(rows=>setState(states=>({...states,personList:rows})))
    }, [])
    
    return(
     <>
      <Typography variant="body1" component="p">{state.person}</Typography>
      <Typography variant="caption" component="p" color="textSecondary">{state.city}, {state.city.country} 
      </Typography>
     </>
    )
    
    const[state,setState]=useState({
    个人列表:[]
    })
    useffect(()=>{
    fetch('/api/persons/',{method'GET',headers:{'Content-Type':'application/json'}})
    .then(res=>res.json())
    .then(rows=>setState(states=>({…states,personList:rows})))
    }, [])
    返回(
    {state.person}
    {state.city},{state.city.country}
    )
    
    这就是我的API目前的设计方式

  • 为什么我要使用原始sql查询?因为我使用的数据库不是在Django应用程序中创建的,所以我没有用于实现Django的ORM的模型
  • 为什么我的查询结构类似json?因为我使用的序列化程序不依赖于模型,也不扩展ModelSerializer类
  • 我的问题是:

  • 这是一个好的、可接受的方法吗
  • 如果数据库结构发生变化,这种设计是否会在可维护性方面带来未来的问题
  • 如果我将CountrySerializer()从name=CharField()更改为country\u name=CharField(),则随后更改API后端逻辑,以将响应的对象键从“name”返回到“country\u name”,我有20个前端模块引用了旧的“name”对象键,那么我可能需要编辑这20个前端模块,将“name”引用更改为“country_name”这种类型的维护是不可避免的,并且被认为是RESTFul API中常见的、可能的遭遇吗?

  • 如果你有一个现有的表,你可以写你的模型来匹配现有的结构,不,嗯,那是可能的。但是,它不是遗留数据库,DB管理员会不时对其进行更改。当DB管理员对现有结构进行更改时,对我的镜像模型进行更改是多余的。DB目前正在完善,主要由另一个应用程序使用。我正在使用的应用程序需要该数据库中的记录。我也不确定,但我认为API应该是从使用它的主应用程序中设计和提供的,而不是从我的应用程序中。如果表偶尔会更改,那么您可能需要也可能不需要调整代码以适应它,无论您是使用模型还是原始SQL执行此操作。因此,如果DB管理员从
    person
    表中删除
    city
    列,20个前端模块都会受到影响,我肯定必须同时调整后端和前端代码,对吗。这种情况在RESTfulAPI中是很正常的,对吗?当然。如果您使用Django的模型来实现这一点,那么更改通常比调整原始SQL查询更加独立。这显然取决于您编写代码的灵活性。无论哪种方式,都没有任何东西阻止您在这里使用Django模型,所以整个问题可能是没有意义的…?如果您有一个现有的表,您可以编写您的模型来匹配现有的结构,不…?嗯,这是可能的。但是,它不是遗留数据库,DB管理员会不时对其进行更改。当DB管理员对现有结构进行更改时,对我的镜像模型进行更改是多余的。DB目前正在完善,主要由另一个应用程序使用。我正在使用的应用程序需要该数据库中的记录。我也不确定,但我认为API应该是从使用它的主应用程序中设计和提供的,而不是从我的应用程序中。如果表偶尔会更改,那么您可能需要也可能不需要调整代码以适应它,无论您是使用模型还是原始SQL执行此操作。因此,如果DB管理员从
    person
    表中删除
    city
    列,20个前端模块都会受到影响,我肯定必须同时调整后端和前端代码,对吗。这种情况在RESTfulAPI中是很正常的,对吗?当然。如果您使用Django的模型来实现这一点,那么更改通常比调整原始SQL查询更加独立。这显然取决于您编写代码的灵活性。无论哪种方式,这里都没有任何东西阻止您使用Django模型,所以整个问题可能是没有意义的…?