AqYoung

分享渗透知识与技巧

0%

Django之MTV框架模式(一)

MTV框架模式

众所周知,一般的Web开发都会遵循 MVC 设计模式的框架。MVC是Model、View、Controller三个单词的简写,分别代表模型、视图、控制器。Django采用了MTV的框架模式,即模型M,模板T和视图V。

本篇博客主要是入门Django的MTV模式展开的。如果你也是Django初学者的话可能会对你有帮助。

Models(模型层)

模型(Model),即数据存取层。主要的职则是:处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。

Django对各种数据库都提供了很好的支持,对不同的数据库,Django提供了统一调用的API,我们可以根据不同的业务需求使用不同的数据库。

下面一个简单的例子展开:

(数据库采用mysql;python的数据库操作引擎采用pymsql伪装)

初始化配置

创建project和app

source venv/django/bin/activate
django-admin startproject djmodels
cd djmodels/
python manage.py startapp app
# 设置pycharm环境
File ->Setting ->Project ->Python Interpreter

配置djmodels/setting.py

# 导入APP
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app.apps.AppConfig',
]
# 数据库配置
DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # mysql数据库连接
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'djmodels',
        'USER': 'root',
        'PASSWORD': 'passwd',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}
# templates文件夹配置,用来放置前端等文件
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 添加templates在djmodels/templates
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# 语言和地区
LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

配置djmodels/init.py

import pymysql

pymysql.install_as_MySQLdb()    # pymysql伪装MySQLdb

数据库变更生成

python manage.py makemigrations
python manage.py migrate

定义模型

在进行定义模型之前需要先了解一下是ORM

ORM(Object Relational Mapping)对象关系映射,是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
可以简单理解为翻译机。

app/models.py

from django.db import models
# 创建一个Person类继承自Model
class Person(models.Model):
    p_name = models.CharField(max_length=16, unique=True)    # unique设置为True,表示字段在表中必须唯一
    p_age = models.IntegerField(default=18, db_column='age')    # d_column自定义数据库column的名称
    # False Representative MAN ,True Representative WONAN
    p_sex = models.BooleanField(default=False, db_column='sex')

    class Meta: # 
        db_table = 'Peopel'    # 自定义数据库表的名称

更多参考:
字段类型|Meta选项

数据库操作 参考上一篇博客(django之数据操作

模型成员objects

1、URL简单配置

在djmodels/urls.py配置

urlpatterns = {
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include('app.urls')),    # 新增配置
}

之后创建app/urls.py

from django.conf.urls import url
from app import views

urlpatterns = {
    url(r'^addperson/', views.add_persons),
}

通过上面的配置之后我们就可以访问: localhost:8000/app/addperson 来访问网页了

更多参考:URL调度

2、数据添加
import random

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from app.models import Person

# add随机的数据
def add_persons(request):
    for i in range(20):
        person = Person()
        num = random.randrange(1000)
        person.p_name = "aqyoung{num}".format(num=num)
        person.p_age = num
        person.p_sex = num % 2
        person.save()

    return HttpResponse("add sucess")
3、fillter&&exclude 过滤器

fillter() 返回符合条件的数据

exclude() 过滤掉符合条件的数据

创建templates/person_list

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PersonList</title>
</head>
<body>
<ul>
    {% for person in persons %}
	        
  • 姓名{{ person.p_name }} 年龄{{person.p_age}}
  • {% endfor %} </ul> </body> </html>

    按照之前的方法新添加URL规则之后

    编写views.py

    def get_persons(request):
        # persons = Person.objects.filter(p_age__gt=50).filter(p_age__lt=500)    # 1
        persons = Person.objects.exclude(p_age__gt=50).filter(p_age__lt=60)    # 2 
        context = {
            "persons": persons
        }
    
        return render(request, 'person_list.html', context=context)

    fillter表示筛选出符合规则的数据,而exclude表示排除符合规则的数据

    所以:如1表示 筛选 p_age>=50 and p_age<=500 的数据

    如2表示 排除 a_age>=50(a<50)and p_age<=60 的数据

    4、Model中自定义crete用来增加默认值

    在app/models的Person类添加如下代码

    p_hobby = models.CharField(max_length=32, null=True, blank=True)
    
    @classmethod
    def create(cls, p_name, p_page=20, p_sex=True, p_hobby='hanppy'):
        return cls(p_name=p_name, p_age=p_page, p_sex=p_sex, p_hobby=p_hobby)

    之后修改在app/views.py添加如下代码

    def add_person(request):
        person = Person.create('lalalal')
        person.save()
        return HttpResponse("create sucess")

    记得重新迁移数据库

    5、all&&order_by&&values 过滤器
    def get_person(request):
    
        person_all = Person.objects.all()        # 返回所有数据
        person_order = Person.objects.order_by('p_age')        # 排序.默认以id排序,这里指定p_age
        person_values = Person.objects.values()            # 一条数据就是一个字典,返回一个列表
        person_get = Person.objects.get(p_name="qq")    # 参数说明 1
        # print(type(person))
        # print(person)
        # for personz in person:
        #     print(personz)
    
        context ={
            "persons": person_all
        }
    
        return render(request, 'preson.html', context=context)

    参数说明:

    get()

    查询条件没有匹配的对象,会抛异常,DoesNotExist
    如果查询条件对应多个对象,会抛异常,MultipleObjectsReturned

    fist()、last()

    默认情况下可以正常从QuerySet中获取
    隐藏bug

    可能会出现first和last获取到的是相同的对象
    解决方法:显式,手动写排序规则

    count()、exists()

    count用来计数、exists判断是否存

    (Templates) 模板层

    模板(Template),即表现层。主要的职责:处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。

    在Django框架中,模板是可以帮助开发者快速生成呈现给用户页面的工具

    模板主要有两个部分:

    ① HTML静态代码
    ② 动态插入的代码段(挖坑,填坑)

    在之前的初始化配置中,已经创建templates目录用来存放html文件,下面列出一些常见的DJango模板标签

    Django 模板标签

    1、模板中的点语法

    属性或者方法    student.gname
    索引            student.0.gname

    2、if 标签

    支持嵌套。标签接受and、or 或not关键字来对多个变量做判断,或对变量取反。

    {% if  condition %}
    	    ...
    	{% endif  %}

    或者

    {%  if condition %}
    	    ...
    	{% else  %}
    	    ...
    	{% endif %}

    或者

    {% if condition %}
            ...	
     	{% elif condition %}
            ...
    	{% endif %}

    3、for 标签

    允许在一个序列上迭代。支持嵌套。

    {% for person in persons %}
    		
  • {{person.p_name}} {% empty %}
  • sorry not find name
  • {% endfor %}
  • 当列表为空或不存在时,执行empty之后的语句

    {{ forloop.counter }} 表示当前是第几次循环,从1数数
    {{ forloop.counter0}}表示当前是第几次循环,从0数数
    {{ forloop.revcounter}}表示当前是第几次循环,倒着数数,到1停
    {{ forloop.revcounter0}}表示当前第几次循环,倒着数,到0停
    {{ forloop.first }} 是否是第一个 布尔值
    {{ forloop.last }} 是否是最后一个 布尔值

    4、ifequal/ifnotequal 标签

    ifequal 如果相等

    {%  ifequal  value1 value2 %}
    		语句
    	{% endifequal %}

    ifnotequal 如果不相等

    注释标签

    单行注释
    
    
    多行注释
        {% comment %}
    			这是多行注释
    		{% endcomment %}

    5、过滤器

    模板过滤器可以在变量被显示前修改它,使用管道字符:

    {{ page | add : -5}} 没有减法过滤器,但是加法里可以加负数
    
    {{ name|lower }} 大写转换为小写。
    
    {{ name|first|upper }} 将第一个元素转化为大写。
    
    {{ name|truncatewords:"3" }} 显示变量的前3个词。
    
    addslashes:添加反斜杠到任何反斜杠、单引号或者双引号前面。
    
    date:按指定的格式字符串参数格式化date或datetime对象,如{{ pub_date|date:"F j, Y" }}。
    
    length:返回变量的长度。

    6、模板继承

    关键字block:挖坑
        {% block XXX%}
    			code
    		{% endblock %}
    
    extends 继承,写在开头位置
        {% extends  '父模板路径' %}
    
    include:    加载模板进行渲染
        格式{% include '模板文件' %}

    声明:

    • 笔者初衷用于分享与交流网络知识,若读者因此作出任何危害网络安全行为后果自负,与作者无关!