博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

路由分发

'''
简介:
django是专注于开发应用的,当一个djang项目特别庞大的时候
所有的路由与视图函数映射关系全部写在总的urls.py很明显太冗余不便于管理

其实django中的每一个应用都可以有自己的urls.py,static文件夹,templates文件夹,基于上述特点,使用django做分组开发非常的简便
每个人只需要写自己的应用即可
最后由组长统一汇总到一个空的django项目中然后使用路由分发将多个应用关联到一起
'''
复杂版本
from app01 import urls as app01_urls
from app02 import urls as app02_urls
# 路由分发 复杂版本
url(r'^app01/', include(app01_urls)),
url(r'^app02/', include(app02_urls)),
# 进阶版本 不需要导入
url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls')),

名称空间

'''
当多个应用在反向解析的时候如果出现了别名冲突的情况,那么无法自动识别
'''
解决方式1>>>:名称空间
   总路由
   url(r'^app01/', include('app01.urls',namespace='app01')),
   url(r'^app02/', include('app02.urls',namespace='app02')),
   reverse('app01:index_name')
   reverse('app02:index_name')
   <a href="{% url 'app01:index_name' %}">app01</a>
   <a href="{% url 'app02:index_name' %}">app02</a>
解决方式2>>>:别名不能冲突(加上自己应用名作为前缀)
   url(r'^index/', views.index,name='app01_index_name'),
   url(r'^index/', views.index,name='app02_index_name'),

伪静态

将url地址模拟成html结尾的样子,看上去像是一个静态文件
目的是为了增加搜索引擎收藏我们的网站的概率以及seo查询几率

本地虚拟环境

requirements.txt
创建虚拟环境类似于重新下载了一个纯净的python解释器
如果反复创建类似于反复下载,会消耗一定的硬盘空间
推荐将所有的模块统一全部下载到本地

django版本区别

django 1.x与2.x 3.x
1.区别
urls.py中的路由匹配方法
  1.x第一个参数正则表达式
      url()
       2.x和3.x第一个参数不支持正则表达式,写什么就匹配什么
      path()
       如果想要使用正则,那么2.x与3.x也有相应的方法
      from django.urls import path,re_path
           re_path 等价于 1.X里面的url方法
2.转换器
五种常用转换器
   str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
   int,匹配正整数,包含0。
   slug,匹配字母、数字以及横杠、下划线组成的字符串。
   uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
   path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
   
自定义
   class MonthConverter:
       regex='\d{2}' # 属性名必须为regex

       def to_python(self, value):
           return int(value)

       def to_url(self, value):
           return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
       
   from django.urls import path,register_converter
   from app01.path_converts import MonthConverter

   register_converter(MonthConverter,'mon')

   from app01 import views


   urlpatterns = [
       path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),

  ]

三板斧本质

# django视图函数必须要返回一个HttpResponse对象
class HttpResponse(HttpResponseBase):
   """
  An HTTP response class with a string as content.

  This content that can be read, appended to or replaced.
  """
   streaming = False

   def __init__(self, content=b'', *args, **kwargs):
       super(HttpResponse, self).__init__(*args, **kwargs)
       # Content is a bytestring. See the `content` property methods.
       self.content = content
       
def render(request, template_name, context=None, content_type=None, status=None, using=None):
       """
      Returns a HttpResponse whose content is filled with the result of calling
      django.template.loader.render_to_string() with the passed arguments.
      """
       content = loader.render_to_string(template_name, context, request, using=using)
       return HttpResponse(content, content_type, status)
 
redirect内部是继承了HttpRespone类

JsonResponse

需求:给前端返回json格式数据
方式1:自己序列化
   d={'name':'ldb','age':18,'hobby':'篮球'}
   res=json.dumps(d,ensure_ascii=False)
   return HttpResponse(res)
方式2:JsonResponse
   from django.http import JsonResponse
   l=[1,22,333,4444,55555]
   return JsonResponse(l,json_dumps_params={'ensure_ascii':False},safe=False)
# JsonResponse返回的也是HttpResponse对象

上传文件

form表单上传文件注意事项
1.method必须是post
   2.enctype参数修改为multipart/form-data
   
<form action="" method="post" enctype="multipart/form-data" class="bg-info">
   <input type="text" name="username">
   <input type="file" name="myfile" class="text-center">
   <input type="submit" class="btn btn-success">
</form>

def func(request):
   if request.method=='POST':
       print(request.POST)
       file_obj=request.FILES.get('myfile')
       print(file_obj.name)  # 获取文件名称
       with open(r'%s' % file_obj.name,'wb') as f:
           for chunks in file_obj.chunks():
               f.write(chunks)
   return render(request,'func.html')

FBV与CBV

FBV
基于函数的视图
CBV
基于类的视图
# 基本使用
url(r'^func4/', views.MyView.as_view()),  # CBV路由配置

from django.views import View
class MyView(View):
   def get(self,request):
       return HttpResponse('get方法')
   def post(self,request):
       return HttpResponse('post方法')
'''
@classmethod 绑定给类的方法,类来调把类当做第一个参数来传递
'''
# 为什么能够自动根据请求方法的不同执行不同的方法
1.突破口
as_view()
2.CBV与FBV路由匹配本质
'''CBV路由配置本质跟FBV一样'''
url(r'^func4/', views.MyView.as_view()),
   等价
   url(r'^func4/', views.view),
3.源码
def as_view(cls, **initkwargs):
           def view(request, *args, **kwargs):
               self = cls(**initkwargs)  # self = MyView() 生成一个我们自己写的类的对象
               return self.dispatch(request, *args, **kwargs)
           return view
    def dispatch(self, request, *args, **kwargs):
       # 获取当前请求并判断是否属于正常的请求(8个)
       if request.method.lower() in self.http_method_names:
           # get请求 getattr(对象,'get')   handler = 我们自己写的get方法
           handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
       else:
           handler = self.http_method_not_allowed
       return handler(request, *args, **kwargs)  # 执行我们写的get方法并返回该方法的返回值