Django API设计最佳实践:使用json\u build\u对象将SQL SELECT查询构造为类似json的结构是否好
我正在开发一个基于web的应用程序,它实现以下功能: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) 在序列化程序中
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目前的设计方式
如果你有一个现有的表,你可以写你的模型来匹配现有的结构,不,嗯,那是可能的。但是,它不是遗留数据库,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模型,所以整个问题可能是没有意义的…?