• Django高级


    MTV与MVC(了解)
    MTV模型(django):
    M:模型层(models.py)
    T:templates
    V:views
    MVC模型:
    M:模型层(models.py)
    V:视图层(views.py)
    C:控制器(Controller) urls.py
    本质:django的MTV也是MVC

    Django中创建多对多表的三种方式

    第一种利用Django ManyToManyFiled自动创建

    class Book(models.Model):
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_length=8, decimal_places=2, max_digits=8)
        publish = models.ForeignKey(to='Publish')
        authors = models.ManyToManyField(to='Author')
    class Author(models.Model):
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=40)
        address = models.CharField(max_length=32)
        
    

    迁移数据库的时候可以自动的创建第三张表

    手动创建

    
    class Book(models.Model):
        name = models.CharField(max_length=32)
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Author')
        info = models.CharField(max_length=32)
    
    • 优点:
      • 可以添加其他字段
    • 缺点:
      • Django的ORM正向查询和反向查询都不能使用

    半自动创建

    class Book(models.Model):
        name = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author'))
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    #book = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))
    # 多对多可以放在任何一个表中,但是放在不同的表中有不同的写法
    
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Author')
        info = models.CharField(max_length=32)
    
    
    
    
    • 优点
      • 可以扩展第三张表
      • 可以利用Django的ORM

    浏览器发送数据的类型

    前后端传输数据编码格式contentType
    urlencoded
    	对应的数据格式:name=jason&password=666
    	后端获取数据:request.POST
    	ps;django会将urlencoded编码的数据解析自动放到request.POST
    formdata
    	form表单传输文件的编码格式
    	后端获取文件格式数据:request.FILES
    	后端获取普通键值对数据:request.POST
    application/json
    	ajax发送json格式数据
    	需要注意的点
    		编码与数据格式要一致
    

    前端有哪些方式可以朝后端发送请求

    方式 方法
    浏览器窗口手动输入网址 get请求
    a标签的href属性 get请求
    form表单 get(默认)/post
    ajax get/post

    Ajax

    Ajax是什么

    Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
    Ajax = 异步 JavaScript 和 XML 或者是 HTML(标准通用标记语言的子集)。
    Ajax 是一种用于创建快速动态网页的技术。
    Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
    通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
    传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

    ajax默认传输数据的编码格式也是urlencoded

    发送Json格式的数据

    脚本

    			$('#d1').click(function () {
    				   $.ajax({
    					   url:'',  // url参数可以不写,默认就是当前页面打开的地址
    					   type:'post',
    					   contentType:'application/json',
    					   data:JSON.stringify({'name':'jason','hobby':'study'}),
    					   success:function (data) {
    						   {#alert(data)#}
    						   {#$('#i3').val(data)#}
    					   }
    				   })
    				});
    

    后端接收

    def index(request):
        if request.method == 'POST':
            print(request.POST)
            print(request.body)
            data = request.body
            # data = decode('utf-8')
            data = str(data, encoding='utf-8')
            data = json.loads(data)
            print(data)
        return render(request, 'index.html')
    

    ajax上传文件

    前端

    <form action="" method="post">
        <input type='file' id="i1" name="myfile">
        <button id="b1" name="myfile">提交</button>
    </form>
    

    js代码

    
        $('#b1').click(function () {
    
            let formdata = new FormData();
            formdata.append('name', 'jason');
            formdata.append('myfile', $('#i1')[0].files[0]);
    
            $.ajax({
                url: '/index/',
                type: 'post',
                data: formdata,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert(data)
                }
    
            })
        })
    

    后端

    from django.shortcuts import render, HttpResponse
    
    
    # Create your views here.
    
    def index(request):
        if request.method == 'POST':
            print(request.POST)
            # print(request.body)
            # data = request.body
            # data = str(data, encoding='utf-8')
            # data = json.loads(data)
            # print(data)
            file = request.FILES.get('myfile')
            if file:
                with open(file.name, 'wb') as f:
                    for line in file.chunks():
                        f.write(line)
    
            return HttpResponse('OJBK')
        return render(request, 'index.html')
    
    
    form表单与ajax异同点
    		1.form表单不支持异步提交局部刷新
    		2.form表单不支持传输json格式数据
    		3.form表单与ajax默认传输数据的编码格式都是urlencoded
    

    分页器源码

    ```python
    
    class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=10, pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数
    
        用法:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        获取数据用page_data而不再使用原始的queryset
        获取前端分页样式用page_obj.page_html
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1
    
        if current_page < 1:
            current_page = 1
    
        self.current_page = current_page
    
        self.all_count = all_count
        self.per_page_num = per_page_num
    
        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager
    
        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)
    
    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num
    
    @property
    def end(self):
        return self.current_page * self.per_page_num
    
    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1
    
            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1
    
        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)
    
        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
    
        page_html_list.append(prev_page)
    
        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)
    
        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)
    
        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)
    ```
    

    自定义分页器

    		后端:
    			book_list = models.Book2.objects.all()
    			# 数据总条数
    			all_count = book_list.count()
    			# 当前页
    			current_page = request.GET.get('page',1)
    			# 示例一个分页器对象
    			page_obj = my_page.Pagination(current_page=current_page,all_count=all_count)
    			# 对总数据进行切片
    			page_queryset = book_list[page_obj.start:page_obj.end]
    		
    		前端:
                     	将book_list全部替换为book_queryset
    
    			{{ page_obj.page_html|safe }}  # 帮你渲染的是带有bootstrap样式的分页器
    			
    
  • 相关阅读:
    【3】hexo+github搭建个人博客的主题配置
    【2】hexo+github搭建个人博客的简单使用
    每日思考(2020/05/06)
    每日思考(2020/05/05)
    每日思考(2020/03/27)
    文件和异常
    每日思考(2020/03/24)
    图形用户界面和游戏开发
    每日思考(2020/03/19)
    面向对象进阶
  • 原文地址:https://www.cnblogs.com/ruhai/p/11025615.html
Copyright © 2020-2023  润新知