django笔记

快速项目启动

  1. conda activate django
  2. django-admin startproject 项目名
  3. cd 项目名
  4. python manage.py startapp app名
  5. 配置 settings.py
    INSTALLED_APPS = [
      ...
      'app名.apps.App名Config', #新增这个,具体就是在app文件夹的apps.py里面的config对象,把这个路径放进来
    ]
    
  6. 在你的app的文件夹下
    创建 templates 文件夹,里面用于放html
    创建 static 文件夹,放置静态文件,树如下
    static
    ├── css 放css
    ├── img 放图片
    └── js 放js

js画图用,模板
https://echarts.apache.org/examples/zh/index.html#chart-type-line

1. 创建项目,生成工程

conda activate django #激活django环境,django-admin就被加入到环境变量了
django-admin startproject 项目名
# 如:
(django) liuab@liuab-VirtualBox:~/django_project$ tree mysite
mysite
├── manage.py 【项目的管理,启动项目,创建app,数据管理】【不要动,但常用】
└── mysite
    ├── __init__.py     
    ├── settings.py     【项目配置,如连接哪个数据库,注册app】   【经常修改】
    ├── urls.py         【url 和 python函数的对应关系】        【经常修改】
    ├── asgi.py         【接收网络请求,支持异步】              【不要动】
    └── wsgi.py         【接收网络请求,支持同步】              【不要动】

2. 创建APP

django工程下的各个的小的应用程序

- 项目
    - app,用户管理【表结构、函数、HTML模板,CSS】
    - app,订单管理【表结构、函数、HTML模板,CSS】
    ...
我们开发较为简洁,用不到多app,项目下创建1个app即可

如何创建一个app:

python manage.py startapp app的名字
# 如:
python manage.py startapp app01

会在当前目录生成一个app

(django) liuab@liuab-VirtualBox:~/django_project/mysite$ tree .
├── app01
│   ├── __init__.py
│   ├── admin.py        不用动 为django默认提供的admin后台管理
│   ├── apps.py         不用动 app启动类
│   ├── migrations      不用动 数据库字段变更记录(自动生成)
│   │   └── __init__.py
│   ├── tests.py        不用动 单元测试
│   ├── models.py      【重要】,对数据库进行操作
│   └── views.py       【重要】,视图函数写在这里
├── manage.py
└── mysite
    ├── asgi.py
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-38.pyc
    │   └── settings.cpython-38.pyc
    ├── settings.py
    ├── urls.py         【url->函数,调用的函数在views编写】
    └── wsgi.py

3. 快速上手

  • 确保 app 已注册 【settings.py】

    将 app01 文件夹下的 apps.py 文件中的 App01Config 类,写在 mysite 中的 settings.py 中的 INSTALLED_APPS 列表里

    INSTALLED_APPS = [
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      'app01.apps.App01Config', #新增这个
    ]
    
  • 编写 url 和 视图函数的对应关系 【urls.py】

    from app01 import views
    
    urlpatterns = [
      # path('admin/', admin.site.urls),
    
      # 该句意思是,当有用户访问 www.xxx.com/index/ 时,会调用 app01/views文件中的index函数
      path('index/', views.index), 
    
    ]
    
  • 编写 views 函数

    from django.shortcuts import render, HttpResponse
    
    def index(request): # 默认需要参数request
      return HttpResponse("欢迎使用")
    
  • 启动django项目

    python manage.py runserver
    

3.1 再写一个页面

urls.py再加一个,views里面再写一个就可以了。

3.2 返回一个模板(引入html)

在你的app内创建templates文件夹,里面用于放html文件

def return_html(request):
    return render(request,"aaaa.html")
    # 寻找html会按照app的注册顺序,去相应的文件夹下的templates文件夹下寻找html

3.3 静态文件 (引入图片,css,js)

图片,css,js都会当作静态文件处理
静态文件也不能乱放,要放在app下的static文件夹中
记得在static文件夹下,创建 img, css, js 这三个用于放置静态文件的文件夹

引用方式一:就是html 的这种方式,但不推荐

引用方式二:
html中

{% load static %} #开头加上这个
<body>
    <img src="{% static 'img/aaa.png' %}" alt="">
body>

方式二有提示,比较好,而且以后可以在settings.py文件中更改 STATIC_URL。
这样如果static文件位置移动后,只要改STATIC_URL就可以对html中引用的静态文件路径同意更改了。

4. 模板语法

django独有的。
具体流程

用户传参数给url,找到对应的view函数

view函数的render 以 字符串 读取了 ”带有django模板语法“的 html文件到内存 ,并根据view函数中传入的参数 ,对html文件进行渲染(将模板语法执行并替换,替换内容,for循环替换成多个语句,等等,基本就是替换内容),然后得到一个 只包含html的字符串,继而将其返回给用户浏览器
即 用户的浏览器不可能读到模板语法的

html中 {{ param }} 是直接显示传入的参数
但如果没有从render传param这个值,则不显示,传了才显示,可以用作显示用户名或密码错误 再定向到当前页面时传一个错误信息
{{param}} 可以红色显示

5. 请求与响应

def return_html(request):
    return render(request,"aaaa.html")
    # 寻找html会按照app的注册顺序,去相应的文件夹下的templates文件夹下寻找html

请求
这里的 request 是一个对象,封装了用户通过浏览器发送过来的所有数据
其有多个属性:

  1. 请求方式 request.method get或post

  2. 接收get请求携带的参数 request.GET
    比如,www.xxx.com/?param1=123¶m2=234
    print(request.GET) 就能将其输出 QueryDist对象

  3. 接收post请求(请求体)携带的参数 request.POST

    QueryDist对象,就可以和一般的dist字典用 .get("key_name") 得到value

响应
return的东西

  1. HttpResponse(‘响应内容’)
  2. render(request,“abab.html”)返回一个html
  3. redirect(“https://www.baidu.com”)返回一个重定向,用于页面跳转,若跳转至当前域名 可直接从/开始写
    一般来说,redirect之后的代码是不会执行的,如果if里面有redirect,满足条件直接跳转走了,不会执行else里的,否则就执行else,所以可以不要else只留个if就行

注意:
post请求 要在html的form表单中 添加 {% csrf_token %} ,否则会报403的错误
(添加了 {% csrf_token %} 之后,提交时会顺当隐含提交一个csrf_token,用于 django 校验请求是不是正常网页发送的,不是的就403)

6. 数据库操作

ORM框架,可以以pymysql mysqldb mysqlclinet 为backend为底层 与数据库进行操作
ORM对我们来说写的代码会更方便更简洁一些

6.1 安装第三方模块

教程 https://pypi.org/project/mysqlclient/#fies

linux:
Note that this is a basic step. I can not support complete step for build for all environment. If you can see some error, you
should fix it by yourself, or ask for support in some user forum. Don’t file a issue on the issue tracker.
You may need to install the Python 3 and MySQL development headers and libraries like so:
$ sudo apt-get install python3-dev default-libmysqlclient-dev build-essential # Debian / Ubuntu
Then you can install mysqlclient via pip now:
$ pip install mysqlclient

记得还要安装mysql服务器
sudo apt-get install mysql-server

6.2 ORM

ORM 可以帮我们做两件事

  • 创建、修改、删除数据库中的表(不用sql语句)。 【但是无法创建数据库】
  • 操作表中的数据(不用写sql语句)

6.2.1 创建数据库

  • 启动mysql服务并进入
    net start mysql
    mysql -uroot -p密码
    
  • 自带工具创建数据库
    create database 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
    show databases;  # 查看创建的数据库
    

6.2.2 Django 连接数据库

  • settings.py中配置修改,将DATABASES替换为:

    # DATABASES = {
    #     'default': {
    #         'ENGINE': 'django.db.backends.sqlite3',
    #         'NAME': BASE_DIR / 'db.sqlite3',
    #     }
    # }
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'rPPG', # 数据库名称
            'USER': 'root',
            'PASSWORD': 'asd',
            'HOST': '', # 哪台机器安装的mysql,留空默认localhost
            'PORT': '3306',
        }
    }
    

6.2.3 Django 操作表

  • 创建表

    首先确定 app 已注册。
    在 app 的 models.py 中 写一个类继承 models.Model

    # Create your models here.
    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        age = models.IntegerField() 
    """
    相当于在mysql中
    create table app01_userinfo(
        id bigint auto_increment primary key,
        name varchar(32),
        password varchar(64),
        age int
    )
    """
    

    在终端执行命令

    python manage.py makemigrations
    python manage.py migrate 
    

    执行完后,进入mysql

    use 数据库名;
    show tables;
    
    +----------------------------+
    | Tables_in_rPPG             |
    +----------------------------+
    | app01_userinfo             | 
    | auth_group                 |  
    | auth_group_permissions     |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |  其他的表不用管
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    +----------------------------+
    11 rows in set (0.00 sec)
    

    可以拿到刚才创建的 app01_userinfo(app名+类名)

    desc app01_userinfo;
    
    +----------+-------------+------+-----+---------+----------------+
    | Field    | Type        | Null | Key | Default | Extra          |
    +----------+-------------+------+-----+---------+----------------+
    | id       | bigint      | NO   | PRI | NULL    | auto_increment |  id就是第几个数据 从1开始
    | name     | varchar(32) | NO   |     | NULL    |                |
    | password | varchar(64) | NO   |     | NULL    |                |
    | age      | int         | NO   |     | NULL    |                |
    +----------+-------------+------+-----+---------+----------------+
    4 rows in set (0.00 sec)
    

    表就创建好了。

  • 增删改表属性

    新增一列时,修改class

    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        age = models.IntegerField() 
        height = models.FloatField(null=True,blank=True)  # 新增
        weight = models.FloatField(default=2) # 新增
    

    若原始表中已有数据,新增属性时,对已有数据的行的该属性存疑,可通过default参数设置默认值,也可以null=True,blank=True允许为空(更常用)


    以后想要再修改表时
    只需在models.py中操作类(增删改),
    然后执行

    python manage.py makemigrations
    python manage.py migrate 
    

    即可。

    desc app01.userinfo     查看表结构
    

6.2.4 用orm操作数据

  • 对于这样一个类:

    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        age = models.IntegerField() 
    
  • 新增数据(增):

     # 新增一行数据
     UserInfo.objects.create(name="张三", password="333", age=18)
     # 如果有参数没写,则按照类中属性的默认(default值 或 null,需要自己在类中设置好)
    

    (查看某表数据的方式,在mysql中 select * from app01_userinfo(表名)

  • 删除数据(删):

     UserInfo.objects.filter(name="张三").delete() # filter是根据条件筛选,里面可以是任一属性,包括id
     
     UserInfo.objects.all().delete() # 删除所有数据
    
  • 获取数据(查):

    UserInfo.objects.all()   # 全部获取
    # 获取表中的所有数据,为QuerySet类型,理解为一个列表,
    # 列表中是一行一行的数据,每一行数据为一个封装好的对象
    # 如果想要获取对各对象的数据,直接用对象调用属性的方式调用即可。
    data_list = UserInfo.objects.all() 
    for obj in data_list:
      print(obj.id, obj,name, obj.password) 
    
    UserInfo.objects.filter(id=1) # 筛选,筛选出来的也是个列表queryset,就算只有一行数据,也是一个只包含一个对象的列表
    UserInfo.objects.filter(id=1).first()  #直接取出第一个对象
    
  • 修改数据(改):

    UserInfo.objects.all().update(password='asdasdasd') # 一个例子,应该就会用了
    

    示例:访问则添加数据
    django笔记_第1张图片

6.3 用户管理案例

  1. 展示用户列表
    • url.py
      ...
      # 用户管理
      path('info_list/',views.info_list)
      
    • views.py
      ...
      def info_list(request):
         data_list =  UserInfo.objects.all() # 获取数据库中所有的用户信息
         return render(request,"info_list.html",{"data_list":data_list})  # 返回一个页面
      
    • info_list.html
      ...
      <body>
          <h1>Info 列表h1>
          <table border="1">
              <thead>
                  <tr>
                      <th>IDth>
                      <th>姓名th>
                      <th>年纪th>
                  tr>
              thead>
              <tbody>
                  {% for obj in data_list %}
                  <tr>
                      <td>{{ obj.id }}td>
                      <td>{{ obj.name }}td>
                      <td>{{ obj.age }}td>
                  tr>
                  {% endfor %}
              tbody>
          table>
      body>
      ...
      
  2. 添加用户
    • url.py

      ...
      path('info_add/',views.info_add)
      
    • views.py

      ...
      def info_add(request):
          if request.method == "GET": # GET请求(直接通过 url 访问)
              return render(request,"info_add.html") # 返回一个页面
          
          # 否则为 POST请求
      
          # 获取用户提交的信息
          name = request.POST.get("name")
          age = request.POST.get("age")
      
          # 添加到数据库
          UserInfo.objects.create(name=name, age=age)
      
          return render(request,"info_add.html") # 仍返回该页面
      
    • info_add.html

      ...
      <body>
          <h1>添加用户h1>
          <form method="post" action="/info_add/"> 
          
              {% csrf_token %}
              <input type="text" name="name" placeholder="请输入名称">
              <input type="text" name="age"  placeholder="请输入年龄">
              <input type="submit" value="提交">
          form>
      body>
      ...
      

      结合 1 2 效果如下:
      django笔记_第2张图片

你可能感兴趣的:(笔记,web开发,django,python,后端)