Python-Django之MTV模型(反向解析+模板+模型)

来自:pixiv 画师( キューソ猫神

  • 目录
    • MTV概念模型
    •  
    • 环境准备
    •  
    • urls
    •  
    • views
    •  
    • template
    •  
    • model

MTV模型

Django的MTV分别代表:

Model(模型):和数据库相关的,负责业务对象与数据库的对象(ORM)。

Template(模板):放所有的html文件模板语法:目的是将白变量(数据库的内容)如何巧妙的嵌入到html页面

View(视图):负责业务逻辑,并在适当的时候调用Model和Template。

此外,Django还有一个URL分发器。它的作用是将一个个URL的页面请求分别发给不同的Views处理,Views再调用相应的Model和Template。

模型图

 

 

环境

Anaconda3+Pycharm(内置Django)

django项目启动命令:

python manage.py runserver 8080

urls

绑定请求路径与函数

 url(r"^[路径]",views.[函数])              #适用正则匹配
 path("[路径]",views.[函数])

正则补充:

^:以xx开始
$:以xx结束
():无命名分组
(?P<name>):命名分组

引入其他urls文件:

url(r"^[路径]",include("[文件路径]"))
path("[路径]",include("文件路径"))

views

写入与url绑定的函数

默认参数:request

request下的方法:

 path                 请求路径
 get_full_path        全路径
 method               请求方法(GET,POST)
 user                 当前登录用户
 session              会话对象,可读写
 cookies              标准python字典对象

返回值:

httpResponse:字符串
render:html               
               render(request,"xx.html",locals())
               render(request,"xx.html",{局部变量})
render_to_response:等同于render少request参数
redirect:重定向到另一个请求路径或另一个网站   
                redirect("/[请求路径]/")
                redirect("[网址]")                     

template

Template=html+python逻辑代码

1.模板语法

html引入static文件方式:

  #方式一
  <script src="/static/jquery.js"></script>
  #方式二
  {% load staticfiles %}
  <script src="{% static 'jquery.js' %}"></script>
  #加入settings文件:
   STATICFILES_DIRS=(
          os.path.join(BASE_DIR, "blog/static"),
                    )

template变量:

引用变量>>

语法:{{ name }}

变量类型:str,list,dict,class

原理:

                #>>>>>>进入django环境      
                python manage.py shell
                t=Template('hello {{ name }}')
                c=Context({'name':'alex'}))
                t.render(c)
                #!一个模板多次渲染更高效!

变量过滤器>>

            过滤器add:{{ dic.age|add:100 }}
            过滤器capfirst:{{ str|capfirst}}
            过滤器cut:{{ str|cut:' ' }}
            过滤器date:{{ Time|date:'Y-m-d' }}
            过滤器default:{{ li2|default:"空" }}
            过滤器default_if_none:{{ li3|default_if_none:'为none' }}
            过滤器safe:{{ a|safe }}
            等同于{% autoescape off%}      
                  {{ a }}     
                  {% endautoescape %}
            过滤器first:{{ str|first }}
            过滤器length:{{ str|length }}
            过滤器slice:{{ str|slice:"2" }}

template标签(tag):

 #if:
        {% if 条件 %}    执行语句
        {% elif 条件 %}   执行语句
            {% else %}  执行语句
        {% endif %}
#for:
        <ul>
        {% for obj in list %}
            <li>{{ obj.name }}</li>
        {% endfor %}
        </ul>
#csrf:
        django在post第一次提交表单时的安全验证,防止csrf(跨站请求)
        form标签中加入{% csrf_token %}解除
#with:
        将后台传出的变量起个别名
        {% with six=qeqqhetqtqej %}
        {{ six }}
        {% endwith %}
#verbatim:
        禁用render
        {% verbatim %}
        {{ age }}
        {% endverbatim %}
#load:
        加载标签库(自定义filter,simple_tag)
        步骤:
                #①在app中创建templatetags包
                #②包下创建xx.py文件,内容:
                 from django import template
                 from django.utils.safestring import mark_safe
                 #register的名字是固定的,不可改变
                    #filter
                    @register.filter()
                    def filter_multi(x,y):
                        return x*y
                    #simple_tag
                    @register.simple_tag()
                    def simple_tag_multi(x,y,z):
                        return x*y*z`
                #③html引入自定义tag:{% load [xx.py] %}
                #④使用
                       {{ var|[函数名]:value% }}
                       {% [函数名]:var var var %}
        #filter与simple_tag区别:
                        filter只能传一个参数,simple_tag可以传多个参数
                        filter可以在if等后使用,simple_tag不可以


2.1模板继承标签

目的:减少代码的冗余

语法:

{% block classinfo %}
{% endblock %}

使用步骤:

#1、创建一个基板文件base.html
#2、放入重复出现的代码
#3、在有差异的代码段加(一个基板文件可以有多段block)
      {% block classinfo %}
        xxx(可以留空)
      {% endblock %}
 #4、其他的html继承这个基板(继承后会自动调用父类下的xxx,可以被多个html继承)
      {% extends "base.html" %}    #必须是在文件的第一行
      #其他不同的代码放入这个盒子
      {% block classinfo %}
         ***不同的代码***
      {% endblock%}

2.2模板添加标签

使用步骤:

#在需要的地方include文件内容
        {% include 'xxx.html' %}

model

数据库模型—-ORM:对象关系映射

ORM功能:操作表、操作字段

QuerySet特征:

QuerySet相当于sql语句,不调用时不执行
QuerySet有缓存,更改查询条件需要重新赋值

单表操作:(一对一)

1、创建

#①models.py:写入对应数据库表的类
            class Book(models.Model):
            name=models.CharField(max_length=20)
            price=models.IntegerField()
            pub_date=models.DateField()
#②setting.py:修改默认数据库
            DATABASES = {
             'default': {
              'ENGINE': 'django.db.backends.mysql',
              'NAME': 'd1101',            #生成的数据库表名
              'USER':'root',
              'PASSWORD':'root',
              'HOST':'localhost',
              'PORT':'3306',
                       }
                       }

#③ 修改默认驱动:!默认驱动MySQLdb不支持python3!
            #工程文件__init__.py添加:
            import pymysql
            pymysql.install_as_MySQLdb()
#④创建:
             命令:
             python manage.py makemigrations   #创建脚本
             python manage.py migrate   #迁移

    #!PyMySQL 0.9.3与Django 2.2不兼容问题!
    #创建后报错,通过报错信息进入base.py:(注释掉如下两行:35/36行)
           if version < (1, 3, 3):
           raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
    #再次创建,再次报错,通过报错信息进入operations.py文件(46行):
         query.decode替换为query.encode
    #创建迁移,完成生成
⑤修改(可选):
    #如需修改对应数据的类,再次创建迁移即可

2、增删改查

增:
#方式一
b=Book(name='php',price=59,pub_date='2019-01-09',author='alex')
b.save()
#方式二
Book.objects.create(name='php',price=59,pub_date='2019-01-09',author='alex')
#其他:字典方式传入
Book.objects.create(**dic)
改:
#方式一
Book.objects.filter(author="egon").update(price='99')
#方式二
b=Book.objects.get(author="egon")
b.price=100
b.save()
删:
Book.objects.filter(id=1).delete()
查:
#全部
Book.objects.all()
#切片
Book.objects.all()[:1]
#步长
Book.objects.all()[::2]
#首
Book.objects.first()
#末
Book.objects.last()
#指定条件,单行
Book.objects.get(id=2)
#指定字段的某个属性
Book.objects.filter(id=2).values("name")
# 指定字段的某些属性 
Book.objects.filter(id=2).values_list("name","price")
#排除条件
Book.objects.exclude(id=2).all()
#去重
Book.objects.all().distinct()
#计数
Book.objects.all().count()
#万能的
Book.objects.filter(price__gt=50).all()
Book.objects.filter(name__contains="p").all()

多表查询:(一对多)[表关系:外键]

                       查:
                                #方式一(了解)
                                publish_obj=Publish.objects.filter(city='南京')[0]
                                Book.objects.filter(publish=publish_obj)
                                    #原理上等同于>>
                                pid=Publish.objects.get(city='南京').id
                                Book.objects.filter(publish_id=pid)
                                #方式二(了解)
                                Publish.objects.filter(city="南京")[0].book_set.all()
                                #方式三(常用)
                                book_list = Book.objects.filter(publish__city='南京')
                        增:
                                #方式一
                                publish_obj = Publish.objects.filter(id=1)[0]
                                Book.objects.create(name='jq',price=67,author='alex',pub_date='2019-01-09',publish=publish_obj)
                                #方式二
                                Book.objects.create(name='java',price=67,author='alex',pub_date='2019-01-09',publish_id=1)

多表查询:(多对多)[表关系:ManyToMany]

#查:
   #查询书的所有作者
      author_list=Book.objects.get(id=3).author.all()
   #等同于
      author_list = Author.objects.filter(book__name='php')
#增:
   #书增加作者
     Book.objects.get(id=3).author.add(Author.objects.get(id=3))
   #等同于
     Book.objects.get(id=3).author.add(3)

#删:
   #删除书的作者
     Book.objects.get(id=3).author.remove(Author.objects.get(id=3))
   #等同于
     Book.objects.get(id=3).author.remove(3)

跨表查询:

#聚合查询:
         Book.objects.all().aggregate(Avg('price'))
         Book.objects.all().aggregate(Sum('price'))
         Book.objects.all().aggregate(Max('price'))
         Book.objects.filter(author__name='alex').aggregate(alex书的数量=Count('id'))
#分组查询:
         Book.objects.values('author__name').annotate(Count('name'))
         Book.objects.values('author__name').annotate(Sum('price'))
#FQ查询:
      #F:将字段值与某个常量做算数、比较操作
         Book.objects.all().update(price=F('price')+10)
         Book.objects.filter(price__gt=90)
      #Q:构建条件搜索(与&或|非~);可以组合关键字查询
         Book.objects.filter(Q(price=55)&~Q(author__name='alex'))
         Book.objects.filter(~Q(author__name='alex'),price=55)

发表回复