Django基础学习笔记

Django开发流程

创建一个django项目:命令:django-admin startproject 项目名

进入到项目并创建一个应用:命令:python manage.py startapp 应用名

确保是使用的python2环境,file -- settings -- Project: -- Project Interpreter -- 更改环境

将应用添加到项目中:在项目下的settings文件中找到INSTALLED_APPS,在最后面写入应用名

在总的项目文件中创建一个模板,templates,在templates下创建一个目录,目录名跟应用同名,在该目录下则可以创建html文件,用于渲染网页

要想使用模板还得在settings文件中找到TEMPLATES,找到DIRS,在列表中写入:os.path.join(BASE_DIR, 'templates')

更改时区的方法:在settings文件中找到TIME_ZONE : 设置为 'Asia/Shanghai'

将语言更改为中文: 在settings文件中找到LANGUAGE_CODE : 设置为 'zh-hans'

设置url(路由): 在项目下找到url,这就是路由的配置地方,但是一般路由的配置是在应用下的urls,这个文件需要自己创建,

创建一个子路由: 在应用下创建一个urls.py文件

让项目中的路由跟子路由联系起来: 在父路由中导入include,然后再新创建一个路由,url(两个参数),第一个参数是要跟网址做匹配的正则
第二个参数: include('子路由的路径,一般是:应用.urls')

然后配置子路由:跟父路由一样导入url模块,定义一个同名的列表 urlpatterns = [],列表中就可以写url()函数了,第一参数同上
第二个参数则是视图函数,还得在子路由中导入views中的视图函数,视图函数在应用下的views.py中编写

编写视图函数: 在views.py中定义函数,接收一个参数request,函数内返回一个response对象:return render()
render中,第一个参数是request,第二个参数是要返回的模板路径(也就是html文件,应用名/模板名)

Django-model

模型类 --- models.py(主要用与数据库跟django的交互)

ORM :
  MVC框架中一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,使开发时不需要面对sql语句,而是通过
  面向对象来操作数据库

model的作用是定义出对象模型,一般都是和数据库里表对应,一个表一个model类,表里面的字段对应model类的属性,

使用models模块,我们可以操作数据库,但是不需要写sql语句,model模块中都给我们封装好了

在models中定义类,继承models.model , model中内部写了sql语句,只需要调用就行了,类对应的也就是数据库中的表

django使用mysql数据库(链接数据库),在setting.py文件中配置
  DATABASES = {
    'defult':{
  'ENGINE':'django.db.backends.mysql',
  'NAME':'test2' #数据库名
  'USER': '用户名'
  'PASSWORD': '密码'
  'HOST': '数据库服务器ip,本地可以使用localhost'
  'PORT': '端口,默认为3306'
}
在项目的init文件内导入pymysql,并且写上pymysql.install_as_MySQLdb()

在定义类中属性时,需要自定义字段类型,例如Charfield,Booleanfield,
  字段类型:
    Charfield : 字符串 , Booleanfield : 布尔值 , IntegerField:整数
在这些字段类型函数里面,参数可以写字段选项(限制字段),字段默认值等
  参数中还可以定义一个verbose_name = ""
    属性值就是在admin后台显示的信息,等于是自定义在admin网页中显示的字段名

元选项():
  在指定的模型类内定义一个元类,不用继承任何类:
  1.可以自定义更改数据库中表的名字
    db_table='自定义的表名'
  2.以汉字形式在后台管理页面显示表名(更改在admin中显示的模型类名)
    verbose_name = ''
    verbose_name_plural = verbose_name

小总结:
  在admin后台管理中用中文显示表信息
    1.模型类中: def __str__(self):
      return self.name

    2.定义字段属性的函数参数中,传入verbose_name='',admin中指定的字段会替换成该值

    3.模型类中定义一个Meta类,不继承任何类,定义类属性,verbose_name = '需要修改成的值'

管理器manager:
  管理器是模型类的一个属性,用于将对象和数据表映射
  任何一个模型类django都对默认创建一个objects管理器,用于和数据库做交互,是ORM的核心

  自定义管理器(可以定义多个):
    定义一个类,继承models.Manager,
      重写方法:
        get_queryset(self):
          return super(BookInfoManager,self).get_queryset()
    作用:
      自定义后,更改查询集(更改之后就是使用自定义的管理器查询了),还可以在自定义类中加上查询时的过滤方法,这个方法在查询时的all()内部就调用了

      还可以增加模型类对象的创建方法(更快速):
        推荐使用第 1 种
          1.在自定义管理器类中定义一个模型类对象创建方法,不过是对象的方法,然后下次创建模型类对象时也可以直接传参
          在方法的最下面要记得返回在方法中创建的对象
            创建模型类对象:
              b = 模型类.自定义的管理器.创建的对象方法(传入数据)

          2.默认在模型类中是不能写init方法的,所以就需要定义一个类方法来代替init接收参数
          在类中定义一个类的方法,然后再创建模型类对象的时候,可以直接传入要设置的表中信息,
          在方法的最下面要记得返回在方法中创建的对象
            创建模型类对象:
              b = 模型类.类方法(传入的数据则是表中的数据)

Django-admin

#admin网页中可以维护数据

创建超级用户:
  python manage.py createsuperuser
  进入admin网页中会提示输入用户密码,输入后便可进入用户管理页面
  在admin网页中可以直接管理数据,也可以自定义数据的显示方式

注册用户:
  在应用的admin中注册(将模型类添加到admin中)
    导入models模快--> admin.site.register(models模块中的类名)

运行项目后,可以在admin网页中,来查看用户,也会有表的数据,

自定义管理页面(admin网页中)

  在models中定义类,继承admin中的ModelAdmin,
  并且在register注册的方法中的第二参数写上类名,表示遵循这个页面的改变

  列表页的显示:
    类里写上例如
      (字段排序):
        list_display = ['id','btitle','bpub_date'](按照自定义的方式排序显示)

      过滤字段,出现在右边:
        list_filter = ['btitle'](按照btitle过滤)

      搜索字段,出现在上方
        search_fields = ['btitle'](按照btitle进行搜索)

      分页
        list_per_page = 2

      添加修改页
        fieldsets = [
          ('base',{'fields':['btitle']}),
          ('super',{'fields':['bpub_date']})
        ]

关联注册:
  在admin.py中新定义一个类,继承admin.StackedInline(也可以继承admin.TabularInline,显示的是表格形式的),
  用来关联注册,图书跟作者,是一对多的关系(一本书可以由几个人写成)
     model = HeroInfo (表示关联model.py中的哪个类,)
     extra = 2 (表示关联的个数)
     嵌入(也可以嵌入多个)
       在管理类(上面的管理网页显示)中写上
         inlines = [HeroInfoInline] (显示在网页中)

Django-views

view.py中主要编写业务逻辑的代码,负责接收接收web请求和返回web响应

url :
  在应用下创建一个urls.py文件为子路由,urlpatterns是一个url()对象实例的列表,一个url有三个参数,
  url(正则,视图函数,名称),若需要从url中捕获一个值,需要在他周围设置一对小括号

自定义参数:
  在url中将正则用小括号括起来就代表会将该正则传给视图函数中,该视图函数必须定义参数接收,
  在接收参数时,在括号内正则前,写上?P<选择接收的参数,也就是在视图函数中定义的参数名>,尖括号中的参数就会
  指定传给视图函数中同名的参数,没有顺序可言

浏览器中分页显示信息:
  在内存中将数据库的sql查询结果序列化后保存起来,按配置的每页记录数,返回不同的列表

在报404错误时,自己写一个页面返回,在templates文件中写一个404.html,在每次报404错误就会显示404.html页面
但是需要设置以下两点

1.settings文件中设置是否调试,设置DEBUG=False,默认为True,开发中为了调试一般就设置为true

2.ALLOWED_HOSTS = [允许访问的电脑地址],括号中写'*'表示任何

3.在模板目录下创建一个404的模板文件

在网页中输出报错路径
  request_path

request对象
  含有的属性:path(请求路径) ,method(请求方式)都是字符串

  方法
    is_ajax(),判断是否是使用的ajax

网址中传入值,并在视图函数中使用request对象接收:
  在url后面加上?,每个值用 & 隔开,例如: index/?a=1&b=2
    通过request.GET['a']获取数据

  如果是index/?a=1&a=2,也就是一键对多值,使用request.GET.getlist()获取,
  得到的是一个列表

POST请求方式:
  一般用于表单,表单项的name属性,就是在试图中的键,
  获取一键对应一值: request.POST['表单项的name']
  获取一键对多值 : request.POST.get('表单项的name')

response对象:
  content :表示返回的内容
  charset : 表示response采用的编码字符集,字符串类型
  status_code : 响应的HTTP响应代码
  content-type : 指定输出的MIME类型

Django-sessionAndCookie

cookie和session的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

5、所以个人建议:
  将登陆信息等重要信息存放为SESSION
  其他信息如果需要保留,可以放在COOKIE中

cookie :
  存储在浏览器中的一段文本信息

  cookie返回给浏览器信息(键值对)
    set_cookie(key,value='',max_age=None,expires=None)
      key , value都是字符串类型,
      max_age 和 expires参数都是过期时间设置,二选一,不设置的话默认两个星期过期
    response = HttpResponse() ,
    response.set_cookie('t','tt')
    return response

  本网站的cookie不能在其他网站访问

response的子类HttpResponseRedirect重定向
  需要重定向的网页HttpResponseredirect('需要定向到的视图url')
  一般直接使用 renturn redirect('需要定向到的视图url')

无状态:
  HTTP协议的特点,无法记录之前的状态,不会记得用户访问过什么页面,

实现状态保持的两种方法:
  session cookie

session:
  session保存数据默认是保存到了数据库,所以使用之前还要迁移
  session就是一个字典对象

  设置session数据存储的位置:
    在settings文件中添加:
      SESSION_ENGINE='django.contrib.sessions.backends.db' (默认的,存储在数据库)
      本地缓存:
        SESSION_ENGINE='django.contrib.sessions.backends.cache'
      数据库和缓存同时使用:
        SESSION_ENGINE='django.contrib.sessions.backends.cache_db'
      redis:
        SESSION_ENGINE = 'redis_sessions.session'
        SESSION_REDIS_HOST = 'localhost'
        SESSION_REDIS_PORT = 6379
        SESSION_REDIS_DB = 0
        SESSION_REDIS_PASSWORD = ''
        SESSION_REDIS_PREFIX = 'session'
  启用session:
    setting文件中:
      向INSTALLED_APPS列表中添加:
      'django.contrib.sessions',

      向MIDDLEWARE_CLASSES列表中添加:
      'django.contrib.sessions.middleware.SessionMiddleware',
      禁用这些会话可以节省性能消耗

使用session:
  往session中写数据:
    request.session['键']=值
    以base64的编码存储在数据库django_session表中
  根据键获取会话的值
    request.session['键']
    也可以request.session.get('键',默认值(不写为None)),拿不到数据会返回默认值

  判断session中是否有指定数据:键值

  清除所有会话
    clear()
  删除当前的会话数据并删除会话的cookie
    flush()
  删除会话
    del request.session['键']

  设置会话过期时间:
    set_expiry(value)
    如果没有指定,则两个星期后过期
    如果value是一个整数,会话将在values秒没有活动后过期
    若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
    如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
    如果value为None,那么会话永不过期

Django-templates

csrf(跨站攻击):
  取消csrf验证,只有请求方式是POST才需要
    注释中间件,在settings文件中的MIDDLEWARE_CLASSES ,找到含有csrf的一行,将其注释
    但是直接注释等于关闭掉了验证,不安全
    使用如下方法:
      在表单的开头标签下面写上 {% csrf %}
模板中引入静态文件:
  {% load staticfile %}

django模板中的语言称为 :
  简称DTL
    输出变量:{{ 变量 }}
    语法: {% for i in xx %}

      {{ forloop.counter }} -- 可以得到当前循环是第几次

      {% if .. %}
        逻辑1
      {% elif .. %}
        逻辑2
      {% else %}
        逻辑3
      {% endif .. %}
        结尾

      {% empty %} --如果循环的对象空的就走这

      {% endfor %} --结尾

    过滤器(基本是运算)太多,用的时候网上查

      语法:
        {% 变量|过滤器 %}
          例如 : 变量|divisibleby:'2' 整除2

    过滤器串联:
      变量|过滤器1|过滤器2

    注释
      {# 单行注释 #}

      {% comment %}
        多行注释
      {% endcomment %}

    反向解析
      好处:
        变更url后,不需要更改对应链接的的属性了,因为链接属性在定义的时候就自动生成了与url相匹配的地址
      例如: href = {% url 'app:show' '指定传给url的参数,可以多写或不写' %}

      父url起别名 include第三个参数,namespace='',为了区分应用

      子url: name = ''

    模板继承
      block标签,在父模版中预留一个区域,让子模版来继承(挖坑),
        {% block 坑名%}
        预留的区域
        {% endblock 坑名 %}

      extends,在子模版中继承
        {% extends '继承于的模板' %}

        继承父模版中预留的区域(填父模板的坑)(子模板中的内容必须写在坑中)
        {% block 坑名 %}
          子模版需要写的内容
        {% endblock 坑名 %}

      传参
        在子模版的视图函数中传入参数在祖先模板中也可以使用

      三层模板继承
        在主模板base中写好html代码,挖一个坑,在base_user中继承base,填base中的坑,然后再挖一个坑,
        写一个user1和user2来继承base_user,并且填base_user中的坑

        可以跨层填坑: 子模板可以填祖先模板挖的坑

    html转义
      django默认转义,可以有办法来设置不转义
        如果在上下文中传递html代码,django会自动转移成其他的字符,会转义的字符(< > ' " &)
        可以在变量后加个safe过滤器,就等于关闭了转移,django会将他识别为html代码执行
        或者将不需要转义的代码写在{% aotuescape off %}{% endautoescape %}标签中

        在模板中定义的变量默认不转义 ,定义变量(使用过滤器) : {% 变量名|default: '...' %}
          想转义就要手动转义

内存文件的操作
  导入cStringIO模块
  验证码
    安装pillow
    利用PIL绘制验证码
      1.创建背景色
      2.创建画布,
      3.构造字体对象
      4.创建画笔
      5.创建文本内容,字体
      6.绘制逐个字符(循环)
        将每个随机绘入的字符保存在一个定义的空字符中
      7.存入seesion保存的字符,用于验证
      8.保存到内存流中,需要使用cstringIO
      9.返回response对象 return HttpResponse(缓存IO对象,'图片/保存在IO中的格式')
      10.新建一个表单视图网页,action写成另一个试图
      11.在另一个视图中接收表单中的输入值,并与session中的字符做比较

调用对象的方法或者属性:
  在views文件中实例化一个模型类的对象,然后传入上下问对象给模板,模板则可以直接调用该对象的属性或方法

上一篇:Socket实现


下一篇:Educational Codeforces Round 64(ECR64)