• django


    http://docs.30c.org/djangobook2

    MVC 设计模式

    首先,我们分成4个Python的文件,(models.py ,views.py , urls.py ) 和html模板文件 (latest_books.html )

    • models.py 文件主要用一个 Python 类来描述数据表。 称为 模型(model) 。 运用这个类,你可以通过简单的 Python 的代码来创建、检索、更新、删除 数据库中的记录而无需写一条又一条的SQL语句。

    • views.py文件包含了页面的业务逻辑。 latest_books()函数叫做视图

    • urls.py 指出了什么样的 URL 调用什么的视图。 在这个例子中 /latest/ URL 将会调用 latest_books()这个函数。 换句话说,如果你的域名是example.com,任何人浏览网址http://example.com/latest/将会调用latest_books()这个函数。

    • latest_books.html 是 html 模板,它描述了这个页面的设计是如何的。 使用带基本逻辑声明的模板语言,如{% for book in book_list %}

    结合起来,这些部分松散遵循的模式称为模型-视图-控制器(MVC)。 简单的说, MVC 是一种软件开发的方法,它把代码的定义和数据访问的方法(模型)与请求逻辑 (控制器)还有用户接口(视图)分开来。

    Django 里更关注的是模型(Model)、模板(Template)和视图(Views),Django 也被称为 MTV 框架 。在 MTV 开发模式中:

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

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

    • V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。

    Django基本配置

      Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能

    1、安装:
      方式一、pip3 install django
      方式二、官网下载
          解压
          python3 setup.py install

    # 添加环境变量 C:Python3Scripts


    2、基本操作:

    • 创建project

        先进入自己指定的目录
        django-admin startproject mysite
      

    • 创建app
      cd mysite
    
      python3 manage.py startapp cmdb
    
      python3 manage.py startapp monitor

      mysite对应的目录结构

      - mysite (配置文件)

        -init

        -settings 配置文件

        -urls URL对应关系

        -wsgi  遵循WSIG规范,uwsgi+nginx

      - manage.py (管理Project)
      - app(cmdb)
        - models.py 数据库操作
        - admin.py 配置Django自带的后台管理
        - apps.py 当前app的配置
        - tests.py 单元测试
        - views.py 做业务处理...

    Django里面没封装socket,当进行socket数据交互时要用到wsgi,生产环境下一般用第三方模块uwsgi和nginx就可以把Django程序跑起来

    • 创建templates目录

        放html文件

        需要在settings.py中加上

    'DIRS': [os.path.join(BASE_DIR,'templates')],
    • 编辑url.py view.py 

        url是路由系统,每个url对应view函数处理业务

        view.py  业务处理

          1、return render(request,模板路径,{'key':'value'})   

          2、return redirect(url) 跳转

          3、return HttpResponse('ok')

    • 运行
      cd mysite
      python3 manage.py runserver 127.0.0.1:8000

    1.urls.py下面指定url,一个url对应一个函数 from cmdb import view

    2.view.py下面写函数,return的html会去templates目录下找

    3.settings.py指定了html在templates目录下,如果POST的方式发送,这行需要注释,否则forbidden

    # 'django.middleware.csrf.CsrfViewMiddleware',

     用户在浏览器中输入url,看到页面展示,整个流程

      url.py中匹配对应的路由系统,去view.py中找对应的函数处理,默认method=get,返回templates中的html。

     静态文件(css,js,图片)

    创建statics文件夹(文件夹名字随意)

    settings.py最后加上

    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'statics'),#这里面的路径一定是创建的文件
    os.path.join(BASE_DIR,'static'),#如果statics和static下面都有相同的js,优先执行statics的,static下面的不执行 )

    css

    创建commons.css

    <link rel="stylesheet" href="/static/commons.css">

    js

    创建commons.js,记得把jquery也放在此目录下

    {% load staticfiles %}#放在html最上面

    <script src="{% static "jquery-1.12.4.js" %}"></script>
    <script src="{% static "commons.js"%}"></script>

    django数据库操作

      类 --> 数据库的表

      字段 --> 列

      对象 --> 一行数据

    创建数据库表sqlite

    models.py

            class UserInfo(models.Model):
                nid = models.AutoField(primary_key=True)
           user_group = models.ForeignKey('UserGroup') username
    = models.CharField(max_length=32) pwd = models.CharField(max_length=64) age = models.IntegerField()
         class UserGroup(models.Model):
           uid = models.AutoField(primary_key=True)
           caption = models.CharField(max_length=64)

    *需要在settings.py下  INSTALLED_APPS加上app名字,否则不能创建表

    termail下执行

      python3 manage.py makemigrations

      python3 manage.py migrate

    需要注意的是,在创建完数据库后,UserInfo表中会出现user_group_id的字段,user_group存在的,代表UserGroup这个对象

    在view.py中,能通过user_group访问对象的属性

    obj = models.UserInfo.objects.all()

    for row in obj:

      row.user_group.uid

      row.user_group.caption

    连接mysql

    *需要自己先创建数据库

    create database day19 charset utf8;

    *django连接mysql用的是MySqlDB,如果用的是python3的话,需要在配置目录的init.py中加上:

    import pymysql
    pymysql.install_as_MySQLdb()

    settings.py

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'day19',
            'USER': 'root',
            'PASSWORD': 'centos',
            'HOST': '192.168.147.147',
            'PORT': '3306',
        }
    }

    数据库基本操作

    a. 查

      models.tb.objects.all()
      models.tb.objects.filter(nid=1)
      models.tb.objects.filter(nid=1).first()

    b. 增
      1.models.tb.objects.create(...)
      2.
      obj = models.tb(...)
      obj.save()
    c. 删
      models.tb.objects.all().delete()
      models.tb.objects.filter(nid=1).delete()
    d. 改
      models.tb.objects.all().update(...)
      models.tb.objects.filter(nid=1).update(...)

    路由系统urls.py

    1、单一路由对应

    1
    url(r'^index$', views.index),

    2、基于正则的路由

    1
    2
    url(r'^index/(d*)', views.index),
    url(r'^manage/(?P<name>w*)/(?P<id>d*)', views.manage),

    利用  url(r'^edit_user_new-(?P<nnid>d+).html$', views.edit_user_new)实现编辑,url中带.html以为是静态文件,权重会高点。

    整个流程  

      user.html中<a href="/edit_user_new-{{ row.nid }}.html">新编辑</a>

      新编辑跳转到这个url,url.py中加url(r'^edit_user_new-(?P<nnid>d+).html$', views.edit_user_new)

      views.py中def edit_user_new(request,nnid)需要带上参数,method是GET

      编辑完之后提交,action="/edit_user_new-{{ obj.nid }}.html"

      

    3、添加额外的参数

    1
    url(r'^manage/(?P<name>w*)', views.manage,{'id':333}),

    4、为路由映射设置别名

    1
    2
    url(r'^home', views.home, name='h1'),
    url(r'^index/(d*)', views.index, name='h2'),

    h1就代指这个url

    <form method="POST" action="{% url 'nnn' nnid=obj.nid %}">

    设置名称之后,可以在不同的地方调用,如:

    • 模板中使用生成URL     {% url 'h2' 2012 %}
    • 函数中使用生成URL     reverse('h2', args=(2012,))      路径:django.urls.reverse
    • Model中使用获取URL  自定义get_absolute_url() 方法

    5、根据app对路由规则进行分类

    1
    url(r'^app01/',include('app01.urls')),

    当访问127.0.0.1:8000/app01/user时,先去匹配前面的app01,然后去app01下面的url.py中匹配

    6、命名空间

    a. project.urls.py

    1
    2
    3
    4
    5
    6
    from django.conf.urls import url,include
     
    urlpatterns = [
        url(r'^a/', include('app01.urls', namespace='author-polls')),
        url(r'^b/', include('app01.urls', namespace='publisher-polls')),
    ]

    b. app01.urls.py

    1
    2
    3
    4
    5
    6
    7
    from django.conf.urls import url
    from app01 import views
     
    app_name = 'app01'
    urlpatterns = [
        url(r'^(?P<pk>d+)/$', views.detail, name='detail')
    ]

    c. app01.views.py

    1
    2
    3
    def detail(request, pk):
        print(request.resolver_match)
        return HttpResponse(pk)

    以上定义带命名空间的url之后,使用name生成URL时候,应该如下:

    • v = reverse('author-polls:detail', kwargs={'pk':11})
    • {% url 'app01:detail' pk=12 pp=99 %}

    django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

    视图函数views.py

      获取请求信息:
        request.POST {'username':'root'..}
        request.GET
        request.FILES

          obj = request.FILES.get(input里面的name)

          文件名 obj.name

          for line in obj.chunks()

        request.method
        request.body = username=root;age=18;gender=male

      响应结果:
        return HttpReponse(..)
        return render(request,'path/a.html',{})
        return redirect('http://www.baidu.com')

    模板

     模板中也有自己的语言,该语言可以实现数据展示

    • {{ item }}
    • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
        forloop.counter
        forloop.first
        forloop.last 
    • {% if ordered_warranty %}  {% else %} {% endif %}
    • extend

        母板:{% block title %}{% endblock %}
        子板:{% extends "base.html" %}
           {% block title %}新内容{% endblock %}

    • include

        子板:{% extends "base.html" %}
           {% block title %}新内容{%include 'small.html'%}{% endblock %} 

    • 字典.key   列表.索引
    • 帮助方法:
      {{ item.event_start|date:"Y-m-d H:i:s"}}
      {{ bio|truncatewords:"30" }}
      {{ my_list|first|upper }}
      {{ name|lower }}

    3、自定义simple_tag(页面展示)

    a、在app中创建templatetags模块

    b、创建任意 .py 文件,如:xx.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/env python
    #coding:utf-8
    from django import template
    from django.utils.safestring import mark_safe
       
    register = template.Library()
       
    @register.simple_tag
    def my_simple_time(v1,v2,v3):
        return  v1 + v2 + v3
       
    @register.simple_tag
    def my_input(id,arg):
        result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
        return mark_safe(result)
    from django import template
    from django.utils.safestring import mark_safe
    register = template.Library()
    
    @register.filter()
    
    def anyway(value,num):
        return 'dassssssssssssssssssssssssssss'+value+str(num)
    @register.filter()
    def ya(value,v):
        temp = "<a href='http://www.baidu.com?t=%s'>%s</a>"%(v,value)
        return mark_safe(temp)

    c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

    1
    {% load xx %}

    d、使用simple_tag

    1
    2
    {% my_simple_time 1 2 3%}
    {% my_input 'id_username' 'hide'%}

    e、在settings中配置当前app,不然django无法找到自定义的simple_tag  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    )

    4、自定义filter(在if条件中做条件时)

    {{ summary|anyway:8 }}

    在页面仅显示内容用simple_tag

     cookie

      - 是用户浏览器上的一个键值对
      - 设置超时时间

      利用cookie可实现:
        - 登录验证
        - 页面显示条数
        - 拖动位置..

      两大忌讳:
        - 敏感信息
        - 简单

    1、获取Cookie:

    1
    2
    3
    4
    5
    6
    request.COOKIES.get('key')
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
        参数:
            default: 默认值
               salt: 加密盐
            max_age: 后台控制过期时间

    2、设置Cookie:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect(url)
     
    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐',...)
        参数:
            key,              键
            value='',         值
            max_age=None,     超时时间
            expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
            path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
            domain=None,      Cookie生效的域名
            secure=False,     https传输
            httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

    由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。

    1
    2
    <script src='/static/js/jquery.cookie.js'></script>
    $.cookie("list_pager_num"30,{ path: '/' });

      设置cookie

        obj = redirect('/app02/groups')
        obj.set_cookie(key='user_name',value=u,max_age=10)
        return obj

      获取cookie

        request.COOKIES.get('user_name')

    session

    session依赖cookie

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)

    SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False

     生成随机字符串保存在客户端,服务器端保存形式字典,{'随机字符串':{'username':'root','password':'pwd'}}

      request.session['user'] = u

      v = request.session.get('user')

    装饰器+session实现登录认证

    from django.shortcuts import render
    from django.shortcuts import redirect
    from django.shortcuts import HttpResponse
    
    from app01 import models
    # Create your views here.
    def auth(func):
        def inner(request,*args,**kwargs):
            v = request.session.get('user')
            if not v:
                return redirect('/app02/login')
            else:
                return func(request,*args,**kwargs)
        return inner
    @auth
    # group = auth(group)
    def group(request):
        # # v = request.session.get('username')
        # if not v:
        #     return redirect('/app02/login')
        # else:
        return render(request,'groups.html')
    @auth
    def user(request):
        return render(request,'user.html')
    
    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        elif request.method == 'POST':
            u = request.POST.get('username')
            p = request.POST.get('pwd')
            v = models.UserInfo.objects.filter(username=u,pwd=p).first()
            if v:
                obj = redirect('/app02/groups')
                # obj.set_cookie(key='user',value=u,max_age=10)
                request.session['user'] = u
                return obj
            else:
                return render(request, 'login.html',{'msg':'用户名或密码错误'})

    主要加了个auth函数,auth函数功能,取session,有执行func,没有的话跳转到login

  • 相关阅读:
    出现,视图必须派生自 WebViewPage 或 WebViewPage错误解决方法
    未能加载文件或程序集“Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad
    快速调试的VS设置
    WebAPI GET和POST请求的几种方(转发)
    Windows无法启动SQL server 代理服务(服务器)错误1067:进程意外终止
    LC.exe exited with code -1 报错
    Linq 合并数据并相加
    C#事务
    vs2013发布时: sgen.exe 已退出 代码为 1
    使用Jenkins部署.Net应用程序
  • 原文地址:https://www.cnblogs.com/hongpeng0209/p/6516357.html
Copyright © 2020-2023  润新知