一. Vue+Django基礎項目知識點
1. vue+django 跨域的問題解決
https://www.cnblogs.com/lovershowtime/p/11572569.html 跨域知識點

在后台 解決跨域問題 使用中間件 作用全局
cors.py
class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response class CORSMiddleware(MiddlewareMixin): def process_response(self,request,response): # 添加響應頭 # 允許你的域名來獲取我的數據 response['Access-Control-Allow-Origin'] = "*" # 允許你攜帶Content-Type請求頭 response['Access-Control-Allow-Headers'] = "Content-Type" # 允許你發送DELETE,PUT response['Access-Control-Allow-Methods'] = "DELETE,PUT" return response
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'api.cors.CORSMiddleware', ]
請求和 ------復雜請求跨域(預檢)
https://www.cnblogs.com/2017Python/articles/7942124.html
https://www.cnblogs.com/xueheng36/p/10638384.html
中間件 cors.py
class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response class CORSMiddleware(MiddlewareMixin): def process_response(self,request,response): # 添加響應頭 # 允許你的域名來獲取我的數據 # response['Access-Control-Allow-Origin'] = "*" # 允許你攜帶Content-Type請求頭 # response['Access-Control-Allow-Headers'] = "Content-Type" # 允許你發送DELETE,PUT # response['Access-Control-Allow-Methods'] = "DELETE,PUT" # 復雜請求 """ 這是vue前端設置的請求頭 headers:{ 'Content-Type':'application/json', //復雜請求頭 在后台要接收請求頭 'k1':'v1' }""" response['Access-Control-Allow-Origin'] = "*" if request.method == "OPTIONS": response['Access-Control-Allow-Headers'] = "Content-Type,k1" response['Access-Control-Allow-Methods'] = "PUT,DELETE" return response
跨域:因為瀏覽器的同源策略,在你請求返回的時候會進行攔截 jsonp 只能發 get 請求 cors 可以發任何請求 ,在響應時加個響應頭就行 同源策略對ajax阻攔 同源策略對src或href屬性的不阻攔 ajax的本質: xhr = new XMLHttpRequest(); xhr.open... xhr.send(...) 解決方案: - JSONP :原理 面試必問 點擊按鈕: 動態添加一個 <script src='http://www.baidu.com/users/'></script> <script> function func(arg){ alert(arg) } </script> 獲取數據之后要刪除 script標簽 <script src='http://www.baidu.com/users/'></script> - CORS - 加響應頭 簡單與復雜請求的區分:http://www.cnblogs.com/wupeiqi/p/5703697.html a. 簡單請求 A網站: <input type="button" value="獲取用戶數據" onclick="getUsers()"> <script src="jquery-1.12.4.min.js"></script> <script> function getUsers() { $.ajax({ url: 'http://127.0.0.1:8000/users/', type:'GET', success:function (ret) { console.log(ret) } }) } </script> 服務商: class UsersView(views.APIView): def get(self,request,*args,**kwargs): ret = { 'code':1000, 'data':'老男孩' } response = JsonResponse(ret) response['Access-Control-Allow-Origin'] = "*" return response b. 復雜請求(性能上的損耗,options預檢,真實的請求,所以要盡量避免發送復雜的請求) A網站: <input type="button" value="獲取用戶數據" onclick="getUsers()"> <script src="jquery-1.12.4.min.js"></script> <script> function getUsers() { $.ajax({ url: 'http://127.0.0.1:8000/users/', type:'POST', data: {'k1':'v1'}, headers:{ 'h1':'asdfasdfasdf' }, success:function (ret) { console.log(ret) } }) } </script> 服務商: class UsersView(views.APIView): def get(self,request,*args,**kwargs): ret = { 'code':1000, 'data':'老男孩' } response = JsonResponse(ret) response['Access-Control-Allow-Origin'] = "*" return response def post(self,request,*args,**kwargs): print(request.POST) ret = { 'code':1000, 'data':'老男孩' } response = JsonResponse(ret) response['Access-Control-Allow-Origin'] = "*" return response def options(self, request, *args, **kwargs): # self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") # self.set_header('Access-Control-Allow-Headers', "k1,k2") # self.set_header('Access-Control-Allow-Methods', "PUT,DELETE") # self.set_header('Access-Control-Max-Age', 10) response = HttpResponse() response['Access-Control-Allow-Origin'] = '*' #允許的跨域名 response['Access-Control-Allow-Headers'] = 'h1' #允許的請求頭 # response['Access-Control-Allow-Methods'] = 'PUT' #允許的請求方法 return response
2. 后台接口API +VUE前端(django REST framework 跨域 基礎案例)
后台API:

modes from django.db import models class Course(models.Model): """ 課程表 """ title = models.CharField(verbose_name='課程名稱',max_length=32) course_img = models.CharField(verbose_name='課程圖片',max_length=64) level_choices = ( (1,'初級'), (2,'中級'), (3,'高級'), ) level = models.IntegerField(verbose_name='課程難易程度',choices=level_choices,default=1) def __str__(self): return self.title class CourseDetail(models.Model): """ 課程詳細 """ course = models.OneToOneField(to='Course',on_delete=models.CASCADE) slogon = models.CharField(verbose_name='口號',max_length=255) why = models.CharField(verbose_name='為什么要學?',max_length=255) recommend_courses = models.ManyToManyField(verbose_name='推薦課程',to='Course',related_name='rc') # 反向關聯 def __str__(self): return "課程詳細:"+self.course.title class Chapter(models.Model): """ 章節 """ num = models.IntegerField(verbose_name='章節') name = models.CharField(verbose_name='章節名稱',max_length=32) course = models.ForeignKey(verbose_name='所屬課程',to='Course',on_delete=models.CASCADE) def __str__(self): return self.name
settings 下urls
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>\w+)/', include('api.urls')), ]
項目下urls
from django.conf.urls import url,include from api.views import course urlpatterns = [ # """ # 方式一 比較冗余 不清晰: # url(r'^home/$', course.CourseView.as_view()), # http://127.0.0.1:8000/api/v1/home/ 獲取多條數據 # url(r'^home/(?P<pk>\d+)/$', course.CourseView.as_view()), # http://127.0.0.1:8000/api/v1/home/1/ 獲取單條數據 # """ # 方式二 比較清晰明了 # 獲取 多條數據 去list方法 # 獲取單條數據 去retrieve 方法 url(r'^home/$', course.CourseView.as_view({'get':'list'})), url(r'^home/(?P<pk>\d+)/$', course.CourseView.as_view({'get':'retrieve'})), # 獲取 choices 中文字 url(r'^test/$', course.test), ]
解決前端vue發送請求 后端跨域----- 中間件 cors.py
class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response class CORSMiddleware(MiddlewareMixin): def process_response(self,request,response): # 添加響應頭 # 允許你的域名來獲取我的數據 response['Access-Control-Allow-Origin'] = "*" # 允許你攜帶Content-Type請求頭 response['Access-Control-Allow-Headers'] = "Content-Type" # 允許你發送DELETE,PUT response['Access-Control-Allow-Methods'] = "DELETE,PUT" return response
settings 配置 INSTALLED_APPS = [ 'django.contrib.admin', 'rest_framework', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'api.cors.CORSMiddleware', ] REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer','rest_framework.renderers.BrowsableAPIRenderer',], 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS':['v1','v2'], # 允許的版本 'VERSION_PARAM':'version', # 參數 'DEFAULT_VERSION':'v1', # 默認版本 }
drf 序列化---serializers/course.py from api import models from rest_framework import serializers class CourseSerializer(serializers.ModelSerializer): """ 課程序列化 """ level = serializers.CharField(source='get_level_display') # 序列化 choices class Meta: model = models.Course fields = ['id','title','course_img','level'] """ 方式一 : 自動序列化 不可控 class CourseDetailSerializer(serializers.ModelSerializer): class Meta: model = models.CourseDetail fields = '__all__' depth=1 #depth關聯深度 1-10之間的數 def get_recommends(self, obj): # 這個序列化里面obj 對象就是 models對應的課程 (obj當前課程) print(obj, "這個對象哈哈哈哈哈是111111111111111111111111111111111111111111111111111") # 獲取推薦的所有課程 queryset = obj.recommend_courses.all() print(queryset, "當前 0課程對應的詳細!!!!!!!!!!") return [{'id': row.id, 'title': row.title} for row in queryset] def get_chapter(self, obj): # 獲取推薦的所有課程 queryset = obj.course.chapter_set.all() return [{'id': row.id, 'name': row.name} for row in queryset] """ # # 方式二: 手動序列化 可控 class CourseDetailSerializer(serializers.ModelSerializer): """ 課程詳細序列化 """ #OneToOneField / ForeignKey /choice 下面這種 序列化 ===> source參數做連表查詢 title = serializers.CharField(source='course.title') # 跨表 img = serializers.CharField(source='course.course_img') # 跨表 level = serializers.CharField(source='course.get_level_display') # 序列化 choices # ManyToManyField 下面這種 序列化 recommends = serializers.SerializerMethodField() chapter = serializers.SerializerMethodField() class Meta: model = models.CourseDetail fields = ['course','title','img','level','slogon','why','recommends','chapter'] def get_recommends(self,obj): # 這個序列化里面obj 對象就是 models對應的課程 (obj當前課程) print(obj,"這個對象哈哈哈哈哈是111111111111111111111111111111111111111111111111111") # 獲取推薦的所有課程 queryset = obj.recommend_courses.all() print(queryset,"當前 0課程對應的詳細!!!!!!!!!!") return [{'id':row.id,'title':row.title} for row in queryset] def get_chapter(self,obj): # 獲取推薦的所有課程 queryset = obj.course.chapter_set.all() return [{'id':row.id,'name':row.name} for row in queryset]
viwes from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet,ViewSetMixin from api.serializers.course import CourseSerializer,CourseDetailSerializer # 序列化 from api import models """ # 方式一: 獲取單條數據 和多條數據 (對應url) class CourseView(APIView): def get(self, request, *args, **kwargs): # # 課程列表接口 # :param request: # :param args: # :param kwargs: # :return: ret = {'code': 1000, 'data': None} try: pk=kwargs.get("pk") if pk: obj=models.Course.objects.filter(id=pk).first() ser=CourseSerializer(instance=obj,many=False) # 通過url參數 去單條數據 else: queryset = models.Course.objects.all() ser= CourseSerializer(instance=queryset, many=True) # 獲取多條數據 ret['data'] = ser.data print(ser.data,"獲取序列化后的數據!!!!!!") except Exception as e: ret['code'] = 1001 ret['error'] = '獲取課程失敗' return Response(ret) """ # 方式二: 獲取單條數據 和多條數據 (對應url) 拆分兩個方法 比較清晰 # 通過url獲取所有數據訪問list方法 # 通過url帶參數獲取單條數據 訪問retrieve 方法 class CourseView(ViewSetMixin,APIView): def list(self,request,*args,**kwargs): """ 課程列表接口 :param request: :param args: :param kwargs: :return: """ ret = {'code':1000,'data':None} try: queryset = models.Course.objects.all() ser = CourseSerializer(instance=queryset,many=True) # 獲取多條數據 ret['data'] = ser.data except Exception as e: ret['code'] = 1001 ret['error'] = '獲取課程失敗' return Response(ret) def retrieve(self,request,*args,**kwargs): """ 課程詳細接口 :param request: :param args: :param kwargs: :return: """ ret = {'code': 1000, 'data': None} try: # 課程ID=2 pk = kwargs.get('pk') # 課程詳細對象 obj = models.CourseDetail.objects.filter(course_id=pk).first() ser = CourseDetailSerializer(instance=obj,many=False) # 通過url參數 去單條數據 ret['data'] = ser.data except Exception as e: ret['code'] = 1001 ret['error'] = '獲取課程失敗' return Response(ret) # 獲取 choices 中文字 def test(request,*args,**kwargs): from django.shortcuts import HttpResponse obj = models.Course.objects.filter(id=2).first() print(obj.title) print(obj.level) # print(obj.get_level_display()) # return HttpResponse('...') # 人工智能 # 2 # 中級![]()
![]()
前台vue:


3. 后台接口API +VUE前端(django REST 基礎案例)知識點補充
https://www.cnblogs.com/wwg945/articles/8868786.html
https://blog.csdn.net/Fellow_Y/article/details/81633850
https://blog.csdn.net/wolf131721/article/details/78920080