-后端人员,写后端,也要写【模板语法】---》xx.html的python代码 -全栈开发-->前后端混合时代,比较多
从今天开始,学的是前后端分离-后端人员,一点前端都不需要动,只需要写接口即可 -全栈开发---》web后端,前端框架(vue,react)
在开发Web应用中,有两种应用模式:1.前后端不分离
客户端看到的内容和所有界面效果都是由服务端提供出来的
(资料图)
2.前后端分离【把前端的界面效果(html
,css
,js
分离到另一个服务端,python服务端只需要返回数据即可)】
前端形成一个独立的网站,服务端构成一个独立的网站
二、API接口为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本【前后端合作】API概念API:应用程序接口(API:Application Program Interface
)
应用程序接口(API:application programming interface)是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过使用 API 函数开发应用程序,从而可以避免编写无用程序,以减轻编程任务简单来说就是通过网络,规定了前后端信息交互规定的URL链接,也就是前后端信息交互的媒介
http://127.0.0.1/books/ 点赞,点踩 就是API接口
URL:长得像返回数据的URL链接https://api.map.baidu.com/place/v2/search
请求方式:get
、post
、put
、patch
、delete
采用get
方式请求上方接口
请求参数:json
或xml
格式的key-value类型数据ak
:6E823f587c95f0148c19993539b99295
region:上海query:肯德基output:json
-早些年 前后端交互使用xml格式----》ajax:异步JavaScript和XML-后来,随着json格式的出现,成了主流,直到现在-以后:一定会出现,比json更高效的交互格式,更安全
响应结果:json或xml格式的数据上方请求参数的output参数值决定了响应数据的格式数据# xml格式https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=xml"""中文会变成上面的样式,上下两个url是一样的意思"""https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=上海&query=肯德基&output=xml#json格式https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=jsonhttps://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=上海&query=肯德基&output=json"""下方是返回的值"""{ "status":0, "message":"ok", "results":[ { "name":"肯德基(罗餐厅)", "location":{ "lat":31.415354, "lng":121.357339 }, "address":"月罗路2380号", "province":"上海市", "city":"上海市", "area":"宝山区", "street_id":"339ed41ae1d6dc320a5cb37c", "telephone":"(021)56761006", "detail":1, "uid":"339ed41ae1d6dc320a5cb37c" } ...]}
三、接口测试工具postmanpostman介绍作为后端,写好了接口,我们自己要测试通过,再给别人用。
而后端测试人员需要测试API接口的时候,总不可能在浏览器里面试用吧,所以有了专业的接口测试工具Postman
-浏览器只能发送get请求,不能自动发送post,delete请求 -postman---》开源软件,只是谷歌浏览器的插件,越做好好,后来可以按装到操作系统上,再后来,收费 -postwoman -很多很多其他的,不同公司用的也可能不一样,你只需要明白一个点,这个工具只是用来发送http请求
postman下载与使用1、官方下载https://www.postman.com/downloads/?utm_source=postman-home----》Postman-win64-Setup.exe2、安装时,双击即可,马上就会出现下图界面3、使用讲解
打开一个新的测试页面后界面如下,返回数据的窗口在没有发送请求之前是空的。点击界面中间的Body,可以选择发送请求的方式,需要注意在使用form-data请求方式,即用form表单传输文件的时候,需要手动选择传输的数据类型
这里返回的结果
四、如何在浏览器中测试我们需要再settings.py
文件中注册rest_framework
才能在浏览器中进行接口测试
INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "app01.apps.App01Config", "rest_framework",]
五、restful规范(重要)概念REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征性状态转移)。 它首次出现在2000年Roy Fielding的博士论文中
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源
事实上,我们可以使用任何一个框架都可以实现符合restful规范的API接口
十条规范
-1 数据的安全保障,通常使用https(http+ssl/tsl)协议 -url链接一般都采用https协议进行传输 -采用https协议,可以提高数据交互过程中的安全性 -2 接口中带api标识-https://api.lqz.com/books(可以写在域名中) -https://www.lqz.com/api/books(也可以写在路由中) 咱们用这个 -3 多版本共存,路径中带版本信息-https://api.lqz.com/v1/login -https://api.lqz.com/v2/login-https://www.lqz.com/api/v1/login -https://www.lqz.com/api/v2/login -4 数据即是资源,均使用名词,尽量不出现动词(最核心的)-接口一般都是用于完成前后台数据的交互,交互的数据我们称之为资源 -接口形式如下 https://api.baidu.com/users https://api.baidu.com/books -特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义、https://api.baidu.com/login -5 资源操作由请求方式决定(method)-操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作 https://api.baidu.com/books - get请求:获取所有书(获取所有) https://api.baidu.com/books/1 - get请求:获取主键为1的书(获取一条) https://api.baidu.com/books - post请求:新增一本书书(新增一条) https://api.baidu.com/books/1 - put请求:修改主键为1的书(整体修改一条) https://api.baidu.com/books/1 - patch请求:修改主键为1的书(局部修改一条) "ps:patch用的不多,一般用put即可" https://api.baidu.com/books/1 - delete请求:删除主键为1的书(删除一条) -6 在请求地址中带过滤条件 https://api.example.com/v1/zoos?limit=10:指定返回记录的数量 https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置 https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数 https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序 https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件 -7 响应中状态码:两套-http响应状态码:1xx:请求正在处理,2xx:成功响应,3xx:重定向,4xx:客户端错误,5xx:服务端错误 "常见的需要记住" 响应状态码2XX200:常规请求201:创建成功 响应状态码3XX301:永久重定向302:暂时重定向 响应状态码4XX403:请求无权限404:请求路径不存在405:请求方法不存在 响应状态码5XX500:服务器异常 -https://blog.csdn.net/li_chunlong/article/details/120787872 -公司内部规定的响应状态码,放在响应体中 {code:0} 咱们后期一般使用100 101 102这种 -8 返回数据中带错误信息 { code:0 msg: "ok/用户名错误"} -9 返回的结果应该符合以下规范---》好多公司不遵循这个 GET 获取所有数据:返回资源对象的列表(数组)[{name:红楼梦,price:99},{name:红楼梦,price:99},{name:红楼梦,price:99}] GET 单个对象:返回单个资源对象:{name:红楼梦,price:99} POST 新增对象:返回新生成的资源对象:{name:西游记,price:99} PUT 修改对象:返回完整的资源对象 :{name:西游记,price:100} DELETE 删除:返回一个空文档 -10 响应数据中带连接 # Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么{ "status": 0, "msg": "ok", "results":[ { "name":"肯德基(罗餐厅)", "img": "https://image.baidu.com/kfc/001.png" } ...]}比较好的接口返回# 响应数据要有状态码、状态信息以及数据本身{ "status": 0, "msg": "ok", "results":[ { "name":"肯德基(罗餐厅)", "location":{ "lat":31.415354, "lng":121.357339 }, "address":"月罗路2380号", "province":"上海市", "city":"上海市", "area":"宝山区", "street_id":"339ed41ae1d6dc320a5cb37c", "telephone":"(021)56761006", "detail":1, "uid":"339ed41ae1d6dc320a5cb37c" } ...]}
六、序列化反序列化api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把【数据转换格式】,序列化可以分两个阶段:
序列化: 把我们识别的数据转换成指定的格式提供给别人
-字典,列表------》json格式存到文件中了-例如:我们在django中获取到的数据默认是模型对象,但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人-read
反序列化:把别人提供的数据转换/还原成我们需要的格式
-例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中。 -write
七、基于Django原生编写五个接口# 以后写的接口,基本上都是五个接口及其变形-查询所有-查询单个-新增一个-修改一个-删除一个# 基于books单表为例,写五个接口-创建book表-表迁移-录入假数据:直接录,后台管理录-写查询所有接口----》遵循restful规范,使用cbv-新增一条数据-----》-查询一条-修改一条:put提交的数据,不能从request.POST中取-删除一条
models.py
form django.db import modelsclass Book(models.Model):name = models.CharField(max_length=32)price = models.CharField(max_length=32)publish = models.CharField(max_length=32)
urls.py
urlpatterns = [path("admin/", admin.site.urls),path("api/v1/books/", views.BookView.as_view()),path("api/v1/books//", views.BookDetailView.as_view()),]
views.py
from django.shortcuts import render,HttpResponse,redirectfrom django.http import JsonResponsefrom .models import Book# 相对导入from django.views import Viewimport jsonclass BookView(View):# 查询所有def get(self, request):# 查询出所有的图书,queryset对象,不能直接给前端books = Book.objects.all()# 转成json格式,给前端# 把quer对象转成列表,然后再使用JsonResponsebook_list = []for book in books:book_list.append({"name": book.name, "price": book.price, "publish": book.publish})# 扩展做了解# return HtpResponse(json.dumps(book_list, ensure_ascii=False))# 指定ensure_ascii为false,前端就显示中文了return JsonResponse(book_list, safe=False, json_dumps_params={"ensure_ascii": False})# JsonRsponse只能放字典或列表# 薪增一个(只能使用urlencoded或form-data编码,使用json形式编码不行,因为json格式编码提交的数据,不能从request.POST中取,从body中)def post(self, request):# 取出前端传入的数据name = request.POST.get("name")price = reqeust.POST.get("price")publish = request.POST.get("publish")# 存到数据库中book = Book.objects.create(name=name, price=price, publish=publish)# 返回新增的对象字典return JsonResponse({"name": book.name, "price": book.price, "publish": book.publish})class BookDetailView(View):def get(self, request, pk):book = Book.objectsfilter(pk=pk).first()# book模型对象转成字典,使用JsonResponse返回return JsonResponse({"id": book.id, "name": book.name, "price": book.price, "publish": book.publish})def put(self, request, pk):# request.POST只能取post提交的urlencoded或form-data编码数据,put提交的取不到# 查到要改的book = Book.objects.filter(pk=pk).first()# 取出前端传入的数据,修改完,保存----》存在问题,因为put提交的取不到# book.name = request.POST.get("name")# book.price = request.POST.get("price")# book.publish = request.POST.get("publish")# book.save()# 前端使用json格式提交,自己保存print(request.body)book_dict=json.loads(request.body)book.name = book_dict.get("name")book.price = book_dict.get("price")book_publish = book_dict.get("publish")book.save()return JsonResponse({"id": book.id, "name": book.name, "price": book.price, "publish": book.publish})def delete(self, request, pk):Book.objects.filter(pk=pk).delete()return JsonResponse(data={})
八、drf介绍和快速使用概念核心思想: 缩减编写api接口的代码
Django REST framework
是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用。在REST framework中,提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。REST framework提供了一个API 的Web可视化界面来方便查看测试接口。
官方文档:https://www.django-rest-framework.org/
github: https://github.com/encode/django-rest-framework/tree/master
特点(了解一下)提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;提供了丰富的类视图、Mixin扩展类,简化视图的编写;丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;多种身份认证和权限认证方式的支持;[jwt]内置了限流系统;直观的 API web 界面;可扩展性,插件丰富安装# djangorestframework: drf 帮助我们快速的实现符合restful规范的接口# django 最新 4.x ,一般都会用最新版的上一版3.x# drf最新支持到djagno 3.x ,最新不支持2.x# 安装drfpip3 install djangorestframework -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/ # 由于你是django2.x 它发现它不支持,它会自动写在dajgno,安装最新的django 4.x
使用drf编写五个接口注意:url的末尾必须要写斜杠符号,不然会报错urls.py
from app01.views import BookViewfrom rest_framework.routers import SimpleRouterrouter = SimpleRouterrouter = SimpleRouter()router.register("books", BookView, "books")urlpatterns = [path("admin/", admin.site.urls),]# 两个列表相加 [1,2,4] + [6,7,8]=urlpatterns += router.urls
views.py
form .serializer import BookSerializerfrom rest_framework.viewsets import ModelViewSetclass BookView(ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer
serializer.py
from rest_framework import serializersform .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = "__all__"
九、drf之APIView源码分析基于APIView写五个接口urls.py
urlpatterns = [path("books/", BookView.as_view()),path("books//", BookDetailView.as_view()),]
views.py
form rest_framework.views import APIView# APIView继承了Django原来的Viewfrom .serializer import BookSerializerfrom rest_framework.response import Responseclass BookView(APIView):# 查询所有def get(self, request):book_list = Book.objects.all()# drf提供了序列化类ser = BookSerializer(instance=book_list, many=True)# 序列化return Response({"code": 100, "msg": "成功", "result": ser.data})def post(self, request):ser = BookSerializer(data=request.data)# 反序列化if ser.is_valid():# 数据校验---》有些不合法禁止ser.save()# 保存到数据库中return Response({"code": 100, "msg": "成功"})class BookDetailView(APIView):# # 查询单条def get(self, request, pk):book = Book.objects.filter(pk=pk).first()ser = BookSerializer(instance=book,many=False)# 序列化return Response({"code": 100, "msg": "成功", "result": ser.data})# 修改一条def put(self, request, pk):book = Book.objects.filter(pk=pk).first()ser = BookSerializer(instance=book,data=request.data)# 反序列化if ser.is_valid():# 数据校验---》有些不合法禁止ser.save()# 保存到数据库中return Response({"code": 100, "msg": "成功"})def delete(self, request, pk):Book.objects.filter(pk=pk).delete()return Response({"code": 100, "msg": "删除成功"})
serializer.py
from rest_framework import serializersfrom .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = "__all__"
CBV源码分析# cbv写法:1 视图中写视图类,继承View,写跟请求方式同名的方法 class BookView(View): def get(self,request): return 四件套 2 在路径用写 path("books/", BookView.as_view()) # 如上写法,为什么能够执行# 前置条件:前端请求,一旦路径匹配成功,就会执行 BookView.as_view()(request传入,)# 入口在 BookView.as_view()--->执行结果---》View中有个as_view类的绑定方法 @classmethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): self = cls(**initkwargs) res=self.dispatch(request, *args, **kwargs) return res return view # 执行结果是view 的内存地址: 请求来了,执行view(request)path("books/", view) # 执行 View类中的as_view方法中的内层的view函数,路由匹配成功,本质是在执行self.dispatch(request, *args, **kwargs) # self是谁的对象?BookView的对象 # 去BookView中dispatch,找不到,去父类,View中找到了 # View这个类的dispatch def dispatch(self, request, *args, **kwargs): # request.method.lower() 如果是get请求, ‘get’ 在这个列表里面 if request.method.lower() in self.http_method_names: # handler=getattr(BookView的对象,"get") # handler就是BookView类中的get方法 handler = getattr(self, request.method.lower()) else: handler = self.http_method_not_allowed # 执行 BookView类中的get方法 (request) return handler(request, *args, **kwargs) # 最终本质跟写fbv的执行流程一样# 最终结论:什么请求方式,就会执行视图类中的什么方法-本身请求来了,匹配成功,会执行view(request)def view(request, *args, **kwargs):return self.dispatch(request, *args, **kwargs)-self.dispatch View类的方法def dispatch(self, request, *args, **kwargs):# request.method请求方式转成小写,必须在列表中才能往下走if request.method.lower() in self.http_method_names:# 反射,去self【视图类的对象:BookView】,去通过get字符串,反射出属性或方法# BookView的get方法handler = getattr(self, request.method.lower(), self.http_method_not_allowed)else:handler = self.http_method_not_allowed# BookView的get方法,加括号,传入requestreturn hander(request, *args, **kwargs)
APIView执行流程-源码分析urls.py
path("books/", views.BookView.as_view()),---》请求来了,执行views.BookView.as_view()()--->现在as_view是APIView的as_view(因为我们把父类从View换成了APIView)
我们点进源码查看可以发现APIView其实继承了View
class APIView(View):
往下查找as_view()的代码
# APIView的as_view方法:view还是原来的view,但是以后再也没有csrf认证了@classmethoddef as_view(cls, **initkwargs):# 调用父类的as_view,父类是Django原生view# 把Django原生view的as_view方法中的闭包函数view拿出来了view = super().as_view(**initkwargs)# csrf_exempt 排除所有csrf的认证# 相当于再所有的方法上面加了这个装饰器return csrf_exempt(view)"从他内部的view我们可以看到他是用派生方法调用父类View中的as_view因此我们说view还是原来的view,但是返回的结果是csrf_exempt(view),回顾装饰器的知识,我们可以知道虽然把装饰器写成了语法糖,但是在运行的时候其实就是把被装饰的函数名称传进来当参数运行,因此这里就是取消了csrf认证的作用"# 路由匹配成功,执行的其实就是csrf_exempt(view)(request)--->而这个view就是View的as_view中的闭包函数view---》然后执行self.dispatch--->self是视图类的对象---》BookView产生的对象---》这时候会执行self.dispatch,根据名称的查找顺序他会查找到APIView的dispatch:def dispatch(self, request, *args, **kwargs):# 这里的参数中的request是Django原生request,老的request# 把老的request包装成了新的request,这个是drf提供的Request类的对象request = self.initialize_request(request, *args, **kwargs):# 到此以后,这个request就是新的了,老的request在request._request这是老的# 把新的request放到了self对象【BookView的对象】self.request = reqeusttry:# 执行了三大认证【认证、频率、权限】,使用新的request,之后会将self.initial(request, *args, **kwargs)# 跟之前一模一样用反射获取执行结果,如果报错就用异常捕获处理if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(), self.http_method_not_allowed)else:handler = self.http_method_not_allowed# 把新的request传入了,视图类的方法中get的request也是新的response = handler(request, *atgs, **kwargs)except Exception as exc:# 在执行3大认证和视图类中方法的过程中,如果出了异常,都能捕获到---》全局异常捕获response = self.handle_exception(exc)self.response = self.finalize_response(request, response, *args, **kwargs)return self.response"上方的request调用了initialize_request方法,这个方法的返回结果产生了一个Request生成的对象,它的源码如下:"def initialize_request(self, request, *args, **kwargs):parser_context = self.get_parser_context(request)return Request(reqeust,parsers=self.get_parsers(),authenticators=self.get_authenticators(),negotiator=self.get_content_negotiator(),parser_context=parser_context)"接着我们点进这个Request类的源码,我们会发现老的request变成了_request属性"def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None):self.request = requestself.parsers = parsers or ()self.authenticators = authenticators or ()self.negotiator = negotiator or self._default_negotiator()self.parser_context = parser_contextself._data = Emptyself._files = Emptyself._full_data = Emptyself._content_type = Emptyself._stream = Empty# 总结:APIView的执行流程1.去除了所以的csrf2.包装了新的request,以后在视图类中用的request Request类的对象,不是原生的了-原生的在:新的request._request3.在执行视图类的方法之前,执行了三大认证4.如果三大认证或视图函数方法执行过程中出了错,会有异常捕获---》全局异常捕获5.以后视图类方法中的request都是新的# 补充:装饰器的基本原理def auth()# 装饰器def add()# 函数# 使用auth装饰add函数@auth# 本质是add=auth(add)def add()# 以后再使用add,其实就是在使用 auth(add) 的返回结果
标签:
一、web应用模式Django框架就是一种web框架,专门用来写web项目,之前学的,写的BBS项目,图书管理系统,用的都
1、本数据来源于百度地图,最终结果以百度地图最新数据为准。2、公交线路:55路→89路,全程约27 8公里你如
近日,懂车帝公布了2023年4月份汽车销量情况,其中,比亚迪汽车销量表现尤为突出,秦PLUSDM-i、海豚、元PLU
女性朋友们现在对于个人的颜值和气质要求都很高,毕竟这个社会就是看脸的,有好的身材和穿搭,你给别人留下
鞭牛士报道“我知道人会变老,所以那一句爱你一定要大声地说。”这首因春晚走红的歌曲《是妈妈是女儿》...
一、新能源车可以开10年吗?新能源车可以开10年吗?这大概是每位新能源车主买车前计算过的一个问题,相比燃
1、1 超声波加湿器代表品牌:小熊加湿器超声波加湿器最大的特点就是驾驶效率高,加湿均匀而且能耗低。2、超
1、拥有四把剑的是贾斯汀站长,爱德华·贾斯汀是贾斯汀太空站(原名精灵太空站)的站长,费得·苏克的同...
上个月,vivo官网上架了新品Y系列的新品vivoY78+,起售价1599元。这次vivoY78+有哪些亮点?硬件配置如何?
EA推出了《模拟人生4》的最新扩展包,让粉丝们非常兴奋。到目前为止,对于《模拟人生4》玩家来说,这是忙碌
5月9日,中国平安举办“平安大讲堂·中国平安保险理赔报告发布与保险趋势观察”活动,本次平安大讲堂围...
嘉里物流(00636)再跌超4%,较年内高点15 62港元已跌超30%。截至发稿,跌4 24%,报10 4港元,成交额1028 03
美的星光科技版风管机自2023年3月14日上线以来备受用户青睐,首发4小时内就突破1300套,上线仅2个月,全网累计销售
今年以来,监管持续“亮剑”,多家中介机构相继被启动立案调查。在业内人士看来,全面注册制背景下,压...
“腾讯游戏正在推进跟英伟达等全球多家顶级厂商的深度合作,尝试将游戏引擎和工具链打造成一个可以跨团...
1、如火如荼的意思是像火那样红,像荼那样白。2、原比喻军容之盛。3、现用来形容旺盛、热烈或激烈。4、荼的
本期债券拟发行总额为人民币5 95亿元,债券品种为资产支持证券(ABS),项目更新至“已反馈”。
点击查看>>>关于2023年开平市基层医疗卫生单位公开招聘中高级专业技术人才面谈评价成绩及入围体检名单公...
一、普尔和追梦只是场上的队友直播吧5月16日讯勇士球员普尔被问到与队友追梦目前的关系。“我给不了你答...
为进一步深化区域“靠谱”党建共建,凝心聚力,打造共建共治共享的社区治理新格局,5月15日下午,“凝聚...
X 关闭
X 关闭