• Django随笔


    入门

    小Demo设计介绍

    • 本示例完成“图书-英雄”信息的维护,需要存储两种数据:图书、英雄
    • 图书表结构设计:
      • 表名:BookInfo
      • 图书名称:btitle
      • 图书发布时间:bpub_date
    • 英雄表结构设计:
      • 表名:HeroInfo
      • 英雄姓名:hname
      • 英雄性别:hgender
      • 英雄简介:hcontent
      • 所属图书:hbook
    • 图书-英雄的关系为一对多

    创建应用

      在项目目录下(有manage.py文件的目录)命令行中执行(booktest为应用名):

        python manage.py startapp booktest

      创建成功后目录为

      

    运行应用命令(ip可以不写,端口号可以不指定 默认8000 )

      python manage.py runserver   ip:port

    设计模型类

    from django.db import models
    class BookInfo(models.Model):
        bittle = models.CharField(max_length=20)
        bpub_date = models.DateTimeField()
        def __str__(self):
            #return self.bittle.encode('utf-8')# python2写法   在3中会报TypeError: __str__returned non-string (type bytes) 错误
            return self.bittle  # python3写法
    
    class HeroInfo(models.Model):
        hname = models.CharField(max_length=10)
        hgender = models.BooleanField()
        hcontent = models.CharField(max_length=1000)
        hbook = models.ForeignKey(BookInfo,on_delete=models.CASCADE)#指定外键   级联删除,也就是当删除主表的数据时候从表中的数据也随着一起删除
        def __str__(self):
            return self.hname

    生成数据表 :

      激活模型:在settings.py 的INSTALLED_APPS 最后添加项目的名字

    生成迁移文件:根据模型类生成sql语句

      执行  python manage.py makemigrations

    执行迁移:执行sql语句生成数据表

      python manage.py migrate

    测试数据操作:

      进入python shell :

        python manage.py shell

    管理操作

    • 创建一个管理员用户

        python manage.py createsuperuser,按提示输入用户名、邮箱、密码

      在前台地址后面加/admin就是管理界面  例:http://127.0.0.1:8000/admin

      管理界面本地化:

       编辑settings.py文件,可以设置编码、时区  

       LANGUAGE_CODE = 'zh-Hans'

       TIME_ZONE = 'Asia/Shanghai'

    向admin注册booktest的模型

      打开admin.py,注册模型

    from django.contrib import admin
    from .models import *
    admin.site.register(BookInfo)

     自定义管理页面 

      修改admin.py

      通过定义ModelAdmin的子类,来定义模型在Admin界面的显示方式

    关联对象

      修改admin.py

    视图

      ①.修改views.py设计界面 例:

    from django.shortcuts import render
    from django.http import *
    def index(request):
        return  HttpResponse('hello world')

      ②.urls.py  在urlpatterns添加路径与界面   例:

    from django.contrib import admin 
    from django.urls import path
    from booktest import  views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('',views.index)
    ]

    (django2.X将url改为path

      path转化器

    文档原文是Path converters,暂且翻译为转化器。

    Django默认支持以下5个转化器:

    • str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    • int,匹配正整数,包含0。
    • slug,匹配字母、数字以及横杠、下划线组成的字符串。
    • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    • path,匹配任何非空字符串,包含了路径分隔符
    • 使用尖括号(<>)从url中捕获值。

      例:path('<int:id>',views.show)

    也可以使用正则表达式  将path改为re_path  (需要引入re_path)

      例:re_path(r'^(d+)$',views.show)

    访问http://localhost:8000/        

    模板

      创建模板的目录

            

    页面设计   

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>hello world</h1>
    </body>
    </html>

    在视图views.py中引入模板

    from django.shortcuts import render
    from django.http import *
    from django.template import RequestContext,loader
    def index(request):
        temp = loader.get_template('booktest/index.html')
        return  HttpResponse(temp.render())#temp.render()  渲染 加载页面内容

      可以用render函数代替

    from django.shortcuts import render
    from django.http import *
    def index(request):
        return render(request,'booktest/index.html')#书写简单  用此方法更多

    效果

    获取传递数据

      利用视图views.py中render的第三个参数传递数据

    from django.shortcuts import render
    from django.http import *
    from .models import *
    def index(request):
        bookList = BookInfo.objects.all()#传递对象
        context={'title':'hello','list':bookList}
        return render(request,'booktest/index.html',context)#context传递参数

    页面接收

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <!--<h1>hello world</h1>-->
    <h1>{{ title }}</h1><!--参数获取-->
    {% for book in list %}   {#在{%  %}里写python代码#}
        <li>{{ book.bittle}}</li>
    {% endfor %}
    </body>
    </html>

    页面效果

    在提交ajax请求是报Forbidden (CSRF token missing or incorrect.错误

      需要添加js(可以直接添加,也可以写成js文件引入)

      $(function () {
        $.ajaxSetup({
            headers: { "X-CSRFToken": getCookie("csrftoken") }
        });
    });
    <!--getCookie函数:-->
    function getCookie(name)
    {
        var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
    
        if(arr=document.cookie.match(reg))
    
            return unescape(arr[2]);
        else
            return null;
    }

     ===================================================================================================================================

    模块

      关联mysql 

         安装包 pip install  mysql-python

            pip install mysqlclient

        创建数据库

         在settings.py的DATABASES配置数据库设置

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'test2',#数据库名
            'USER': 'root',#mysql账号
            'PASSWORD': '5418854188',#mysql密码
            'HOST': 'localhost',#数据库服务器ip
            'PORT': '3306',#mysql 端口
        }
    }

       

      之后正常开发(详情参考上面)  创建应用 python manage.py startapp booktest

                     settings.py  INSTALLED_APPS添加应用

                     定义模型

                     定义属性

                     迁移(生成迁移文件:python manage.py makemigrations,执行迁移:python manage.py migrate)

                    

    #default,blank是python层面的对象,不影响数据库表结构,不需要重新迁移

      ===========================================================================================================================

    存储session

    • 使用存储会话的方式,可以使用settings.py的SESSION_ENGINE项指定
    • 基于数据库的会话:这是django默认的会话存储方式,需要添加django.contrib.sessions到的INSTALLED_APPS设置中,运行manage.py migrate在数据库中安装会话表

    使用Redis缓存session

    • 会话还支持文件、纯cookie、Memcached、Redis等方式存储,下面演示使用redis存储
    • 安装包
      pip install django-redis-sessions
    
    • 修改settings中的配置,增加如下项
      SESSION_ENGINE = 'redis_sessions.session'
      SESSION_REDIS_HOST = 'localhost'
      SESSION_REDIS_PORT = 6379
      SESSION_REDIS_DB = 0
      SESSION_REDIS_PASSWORD = ''
      SESSION_REDIS_PREFIX = 'session'
    
    • 管理redis的命令
      启动:sudo redis-server /etc/redis/redis.conf
      停止:sudo redis-server stop
      重启:sudo redis-server restart
      redis-cli:使用客户端连接服务器
      keys *:查看所有的键
      get name:获取指定键的值
      del name:删除指定名称的键

    ===============================================================================================================================================================================

    管理静态文件

    • 项目中的CSS、图片、js都是静态文件

       1.在settings 文件中定义静态内容(STATIC_URL :逻辑路径(虚拟路径) 可以没有真实文件夹,但模板中路径会先匹配此路径,然后在通过下面的配置(物理路径)找文件)

    STATIC_URL = '/static/' 
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static'),
    ]

      2.在项目根目录下创建static目录,再创建当前应用名称的目录

       例: mysite/static/myapp/

      3.在模板中可以使用硬编码

      例:/static/my_app/myexample.jpg
      
     4.也可以
    在模板中可以使用static编码
      例:
    { % load static from staticfiles %} {#在模板中引入模块#}
    <img src="{ % static "my_app/myexample.jpg" %}" alt="My image"/>

     ==============================================================================================================================

    中间件

    ===================================================================================================================================

    上传文件

    • 当Django在处理文件上传的时候,文件数据被保存在request.FILES
    • FILES中的每个键为<input type="file" name="" />中的name
    • 注意:FILES只有在请求的方法为POST 且提交的<form>带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象
    • 使用模型处理上传文件:将属性定义成models.ImageField类型
    
    
    pic=models.ImageField(upload_to='cars/')
    • 注意:如果属性类型为ImageField需要安装包Pilow
    • 图片存储路径
      • 在项目static目录下创建media文件夹
      • 图片上传后,会被保存到“/static/media/cars/图片文件”
      • 打开settings.py文件,增加media_root项
    MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
    • 使用django后台管理,遇到ImageField类型的属性会出现一个file框,完成文件上传
    • 手动上传的模板代码
      <!DOCTYPE html>
      <html>
      <head>
          <title>文件上传</title>
      </head>
      <body>
          <form method="post" action="/upload/" enctype="multipart/form-data">
              {% csrf_token %}
              <input type="text" name="title"><br>
              <input type="file" name="pic"/><br>
              <input type="submit" value="上传">
          </form>
      </body>
      </html>
    • 添加视图路径
      path('upload/',views.upload)
    • 手动上传的视图代码
      from django.conf import settings
      import os
      def upload(request):
              if request.method == "POST":
                  f1 = request.FILES['pic']
                  #fname = '%scars\%s' % (settings.MEDIA_ROOT, f1.name)
                  fname = os.path.join(settings.MEDIA_ROOT, f1.name)
                  with open(fname, 'wb') as pic:#以二进制读写文件
                      for c in f1.chunks():
                          pic.write(c)
                  return HttpResponse("ok")
              else:
                  return HttpResponse("error")
    ==========================================================================================================================================================================

    分页

    • Django提供了一些类实现管理数据分页,这些类位于django/core/paginator.py中
    Paginator对象
    • Paginator(列表,int):返回分页对象,参数为列表数据,每面数据的条数

    属性

    • count:对象总数
    • num_pages:页面总数
    • page_range:页码列表,从1开始,例如[1, 2, 3, 4]

    方法

    • page(num):下标以1开始,如果提供的页码不存在,抛出InvalidPage异常

    异常exception

    • InvalidPage:当向page()传入一个无效的页码时抛出
    • PageNotAnInteger:当向page()传入一个不是整数的值时抛出
    • EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出
    Page对象

    创建对象

    • Paginator对象的page()方法返回Page对象,不需要手动构造

    属性

    • object_list:当前页上所有对象的列表
    • number:当前页的序号,从1开始
    • paginator:当前page对象相关的Paginator对象

    方法

    • has_next():如果有下一页返回True
    • has_previous():如果有上一页返回True
    • has_other_pages():如果有上一页或下一页返回True
    • next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
    • previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
    • len():返回当前页面对象的个数
    • 迭代页面对象:访问当前页面中的每个对象
    例:

    1.创建视图pagTest

    from django.core.paginator import Paginator
    def pagTest(request,pIndex='1'):
        list1 = HeroInfo.objects.all()
        p = Paginator(list1, 10)
        pIndex = int(pIndex)
        list2 = p.page(pIndex)
        plist = p.page_range
        return render(request, 'booktest/pagTest.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})

    2.配置url

    path('page/<str:pIndex>/',views.pagTest)

    3.定义模板pagTest.html

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    <ul>
    {%for area in list%}
    <li>{{area.id}}--{{area.hname}}</li>
    {%endfor%}
    </ul>
    
    {%for pindex in plist%}
    {%if pIndex == pindex%}
    {{pindex}}&nbsp;&nbsp;
    {%else%}
    <a href="/page/{{pindex}}/">{{pindex}}</a>&nbsp;&nbsp;
    {%endif%}
    {%endfor%}
    </body>
    </html>

     =====================================================================================================

    富文本编辑器

    • 安装django-tinymce    pip install django-tinymce
    • 在settings的INSTALLED_APPS添加应用'tinymce'
    • 在settings.py中添加编辑配置项
    TINYMCE_DEFAULT_CONFIG = {
        'theme': 'advanced',
        'width': 600,
        'height': 400,
    }

      配置url

    path('tinymce/',include('tinymce.urls')),

      在admin中使用需要在模型类中进行配置 例:

    from django.db import models
    from tinymce.models import HTMLField
    class HeroInfo(models.Model):
        ...
        hcontent = HTMLField()

     自定义使用

    def editor(request):
        return render(request, 'other/editor.html')
    path('editor/',views.editor),
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <script type="text/javascript" src='/static/tiny_mce/tiny_mce.js'></script>
        <script type="text/javascript">
            tinyMCE.init({
                'mode':'textareas',
                'theme':'advanced',
                'width':400,
                'height':100
            });
        </script>
    </head>
    <body>
    <form method="post" action="/content/">
        <input type="text" name="hname">
        <br>
        <textarea name='hcontent'>哈哈,这是啥呀</textarea>
        <br>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

      

      

  • 相关阅读:
    scrapy Request方法
    from lxml import etree报错
    python文件管道 下载图集
    scrapy基本爬虫,采集多页
    python操作excel xlwt (转)
    matplotlib 设置标题 xy标题等
    matplotlib 饼状图
    acwing 600. 仰视奶牛
    LeetCode 684. 冗余连接
    LeetCode 200. 岛屿数量
  • 原文地址:https://www.cnblogs.com/jokerq/p/8724422.html
Copyright © 2020-2023  润新知