Django进阶

Posted baicai37

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django进阶相关的知识,希望对你有一定的参考价值。

Django之静态文件配置

以登录功能为例:

如果我们用在templates写了一个登录功能的页面,并且想使用样式,但是不能用cdn的形式,那么我们只能将bootstrap,以及jQuery的文件下到本地,不过在Django的项目中怎么导入呢?

下面一步步介绍:

"""
我们将html文件默认都放在templates文件夹下
我们将网站所使用的静态文件默认都放在static文件夹下

静态文件
    前端已经写好了的 能够直接调用使用的文件
        网站写好的js文件
        网站写好的css文件
        网站用到的图片文件
        第三方前端框架
        ...
        拿来就可以直接使用的
"""

注意:

# django默认是不会自动帮你创建static文件夹 需要你自己手动创建
一般情况下我们在static文件夹内还会做进一步的划分处理
    -static
--bootstrap
--js --css --img 其他第三方文件
"""
在浏览器中输入url能够看到对应的资源
是因为后端提前开设了该资源的借口
如果访问不到资源 说明后端没有开设该资源的借口
"""

准备:

1、新建static文件夹,并下载好的bootstrap和jQuery按照之前的教程下载并放到static文件夹中(或者是其他的静态文件)

 技术图片

静态文件配置

在项目配置文件settings.py中配置静态文件

方法一:在项目配置文件settings.py配置静态文件

settings.py

# Static files (CSS, javascript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = /static/      # 类似于访问静态文件的令牌,如果想要访问静态文件,就必须以static开头,我们约定俗成是static,令牌也可以不是static,看项目需求

#静态文件配置
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,"static"),   # 列表说明可以有多个
    os.path.join(BASE_DIR,"static1"),
    os.path.join(BASE_DIR,"static2"),
]

ps:路径问题举例:

#例如:href里的静态文件路径
<link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
判断到是/static/开头,符合令牌条件,然后会到STATIC_URLS中的各个目录路径查找bootstrap-3.3.7-dist/css/bootstrap.min.css资源

#如果STATIC_URLS中第一个目录没有就到第二个目录查找,依次查找下去,都没有才会报错

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login),
]

views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
#login
def login(request):
    # 返回一个登录界面
    return render(request,"login.html")

login.html,注意此时导入的路径直接/static/开头,不用加../回到上一级

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="/static/js/jQuery_3.5.1.js"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>

</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" >
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

浏览器访问:

技术图片

 方法二:在settings.py配置好静态后,再在login.html文件中使用模板语法,动态导入本地静态资源(建议使用)

settings.py

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = /static/

#静态文件配置
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,"static")
]

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!--类似于导模块,这样html文件就能动态感知到本地静态资源的令牌,再写静态资源路径时也不用写令牌了-->
    {% load static %}
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="{% static "bootstrap-3.3.7-dist/css/bootstrap.min.css" %}" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="{% static "js/jQuery_3.5.1.js" %}"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="{% static "bootstrap-3.3.7-dist/js/bootstrap.min.js" %}"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" >
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

回顾知识:

# form表单默认时get提交
http://127.0.0.1:8000/login/?username=alias&password=123

# form表单action参数
    1.不写 默认朝当前所在的url提交数据
    2.全写 指名道姓
    3.只写后缀 /login/

注意一个前期form的method的方式改为post时要注意的情况:

改为post之后浏览器访问会出现403:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!--类似于导模块-->
    {% load static %}
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="{% static "bootstrap-3.3.7-dist/css/bootstrap.min.css" %}" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="{% static "js/jQuery_3.5.1.js" %}"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="{% static "bootstrap-3.3.7-dist/js/bootstrap.min.js" %}"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" method="post">
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

浏览器访问

技术图片

 解决方法1:

# 在前期我们使用django提交post请求的时候 需要取配置文件中注释掉一行代码
MIDDLEWARE = [
    django.middleware.security.SecurityMiddleware,
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    # ‘django.middleware.csrf.CsrfViewMiddleware‘,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
]

解决方法2:在form标签下面第一行添加  {% csrf_token %}

<form action="" method="post">
    {% csrf_token %}
    <p>
      用户名: <input type="text" name="username" class="form-control">
    </p>
    <p>
      密码: <input type="password" name="password" class="form-control">
    </p>
    <input type="submit" class="btn btn-success btn-block">
</form>

request对象方法初识

在views.py中的视图层方法里添加一个print(request),以Debug模式启动

技术图片

request.method:返回请求方式,并且是全大写的字符串形式 

示例:

urls.py

技术图片
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login),
]
urls.py

views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
#login

def login(request):
    # 返回一个登陆界面
    """
    get请求和post请求应该有不同的处理机制
    :param request: 请求相关的数据对象 里面有很多简易的方法
    :return:
    """
    # print(type(request.method))  # 返回请求方式 并且是全大写的字符串形式  <class ‘str‘>
    # if request.method == ‘GET‘:
    #     print(‘来了 老弟‘)
    #     return render(request,‘login.html‘)
    # elif request.method == ‘POST‘:
    #     return HttpResponse("收到了 宝贝")
    
    if request.method == POST:
        return HttpResponse("收到了 宝贝")
    return render(request, login.html)

login.html

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!--类似于导模块-->
    {% load static %}
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="{% static "bootstrap-3.3.7-dist/css/bootstrap.min.css" %}" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="{% static "js/jQuery_3.5.1.js" %}"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="{% static "bootstrap-3.3.7-dist/js/bootstrap.min.js" %}"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" method="post">
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>
login.html

request.POST:获取用户提交的post请求数据(不包含文件)

request.POST.get():获取列表的最后一个元素

urls.py

技术图片
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login),
]
urls.py

views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
#login
def login(request):
    """
    get请求和post请求应该有不同的处理机制,可以使用request的对象方法
    :param request:请求相关的数据对象,里面有很多简易的方法
    :return:
    """
    # print(request.method)    # request.method:返回请求方式,并且是全大写的字符串形式
    if request.method == "POST":
        print(request.POST)    # <QueryDict: {‘username‘: [‘alias‘], ‘password‘: [‘123‘], ‘hobby‘: [‘111‘, ‘222‘, ‘333‘]}>
        username = request.POST.get("username")
        print(username,type(username))   # alias <class ‘str‘>
        hobby = request.POST.get("hobby")
        print(hobby,type(hobby))     # 333 <class ‘str‘>
        
        return HttpResponse("收到了宝贝")
    return render(request, "login.html")

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!--类似于导模块-->
    {% load static %}
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="{% static "bootstrap-3.3.7-dist/css/bootstrap.min.css" %}" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="{% static "js/jQuery_3.5.1.js" %}"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="{% static "bootstrap-3.3.7-dist/js/bootstrap.min.js" %}"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" method="post">
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <p>
                        <input type="checkbox" name="hobby" value="111">111
                        <input type="checkbox" name="hobby" value="222">222
                        <input type="checkbox" name="hobby" value="333">333
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

request.POST.getlist():获取整个列表

urls.py

技术图片
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login),
]
urls.py

views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
#login
def login(request):
    """
    get请求和post请求应该有不同的处理机制,可以使用request的对象方法
    :param request:请求相关的数据对象,里面有很多简易的方法
    :return:
    """
    # print(request.method)    # request.method:返回请求方式,并且是全大写的字符串形式
    if request.method == "POST":
        print(request.POST)    # <QueryDict: {‘username‘: [‘alias‘], ‘password‘: [‘123‘], ‘hobby‘: [‘111‘, ‘222‘, ‘333‘]}>
        # username = request.POST.get("username")
        # print(username,type(username))   # alias <class ‘str‘>
        # hobby = request.POST.get("hobby")    # get只会获取列表最后一个元素
        # print(hobby,type(hobby))     # 333 <class ‘str‘>
        username = request.POST.getlist("username")  # getlist会获取整个列表
        print(username, type(username))  # [‘alias‘] <class ‘list‘>
        hobby = request.POST.getlist("hobby")    # getlist会获取整个列表
        print(hobby, type(hobby))  # [‘111‘, ‘222‘, ‘333‘] <class ‘list‘>
        """
        总结:
        get只会获取列表最后一个元素
        """
        return HttpResponse("收到了宝贝")
    return render(request, "login.html")

login.html

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!--类似于导模块-->
    {% load static %}
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="{% static "bootstrap-3.3.7-dist/css/bootstrap.min.css" %}" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="{% static "js/jQuery_3.5.1.js" %}"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="{% static "bootstrap-3.3.7-dist/js/bootstrap.min.js" %}"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" method="post">
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <p>
                        <input type="checkbox" name="hobby" value="111">111
                        <input type="checkbox" name="hobby" value="222">222
                        <input type="checkbox" name="hobby" value="333">333
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>
login.html

request.GET:获取用户提交的get请求数据(不包含文件),用法和POST一样

urls.py

技术图片
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login),
]
urls.py

views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
#login
def login(request):
    """
    get请求和post请求应该有不同的处理机制,可以使用request的对象方法
    :param request:请求相关的数据对象,里面有很多简易的方法
    :return:
    """
    # print(request.method)    # request.method:返回请求方式,并且是全大写的字符串形式
    if request.method == "POST":
        return HttpResponse("收到了宝贝")
    # 获取url后面携带的参数
    # http://127.0.0.1:8000/login/?username=alias&password=123&hobby=111&hobby=222&hobby=333
    print(request.GET)   # <QueryDict: {‘username‘: [‘alias‘], ‘password‘: [‘123‘], ‘hobby‘: [‘111‘, ‘222‘, ‘333‘]}>
    print(request.GET.get("username"))    # get只获取列表最后一个元素,并且是字符串类型
    print(request.GET.getlist("hobby"))   # getlist 获取整个列表
    return render(request, "login.html")

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!--类似于导模块-->
    {% load static %}
    <!-- Bootstrap3 核心 CSS 文件,本地导入 -->
    <link href="{% static "bootstrap-3.3.7-dist/css/bootstrap.min.css" %}" rel="stylesheet">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="{% static "js/jQuery_3.5.1.js" %}"></script>
    <!-- Bootstrap3 核心 JavaScript 文件 -->
    <script src="{% static "bootstrap-3.3.7-dist/js/bootstrap.min.js" %}"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1 class="text-center">登录界面</h1>
                <form action="" method="get">
                    <p>
                        用户名: <input type="text" name="username" class="form-control">
                    </p>
                    <p>
                        密码: <input type="password" name="password" class="form-control">
                    </p>
                    <p>
                        <input type="checkbox" name="hobby" value="111">111
                        <input type="checkbox" name="hobby" value="222">222
                        <input type="checkbox" name="hobby" value="333">333
                    </p>
                    <input type="submit" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

总结:

request.method # 返回请求方式 并且是全大写的字符串形式  <class ‘str‘>
request.POST  # 获取用户post请求提交的普通数据不包含文件
    request.POST.get()  # 只获取列表最后一个元素
    request.POST.getlist()  # 直接将列表取出
request.GET  # 获取用户提交的get请求数据
    request.GET.get()  # 只获取列表最后一个元素
    request.GET.getlist()  # 直接将列表取出

"""
get请求携带的数据是有大小限制的 大概好像只有4KB左右
而post请求则没有限制
"""

pycharm链接数据库(mysql

pycharm中有类似Navicat一样的数据库客户端软件

软件位置

1、右上角

技术图片

2、pycharm左下角

技术图片

 3、如果上面两个都没找到,在settings-Plugins里面搜database查看圈起来的插件是否安装了(默认都是安装的)

技术图片

 软件使用

1、点击一下

技术图片

 2、点击加号

技术图片

 3、点击mysql,一定要先安装对应的驱动

技术图片

 4、安装好对应驱动后,测试连接

技术图片

测试连接,测试成功后点击apply==>点击ok

技术图片

 5、进入软件视图

技术图片

 6、在Navicat里先创建个表

7、在pycharm里面刷新,查看

技术图片

技术图片

 8、按钮介绍

技术图片

Django链接数据库(mysql)

Django默认使用的数据库是sqlite3

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    default: {
        ENGINE: django.db.backends.sqlite3,
        NAME: os.path.join(BASE_DIR, db.sqlite3),
    }
}

修改数据库为mysql

1、配置文件中配置

把原有的数据库配置注释掉

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

# 把原有的数据库配置注释掉
# DATABASES = {
#     ‘default‘: {
#         ‘ENGINE‘: ‘django.db.backends.sqlite3‘,
#         ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘),
#     }
# }
# 连接MySQL数据库
DATABASES = {
    default: {
        ENGINE: django.db.backends.mysql,
        NAME: day60,    # name对应数据库的名字
        USER: root,
        PASSWORD: 123456,
        HOST: 127.0.0.1,
        PORT: 3306,
        CHARSET: utf8
    }
}

2、代码声明

#django默认用的是mysqldb模块链接MySQL
    但是该模块的兼容性不好 需要手动改为用pymysql链接
    
# 你需要告诉django不要用默认的mysqldb还是用pymysql
# 在项目名下的init或者任意的应用名下的init文件中书写以下代码都可以

这里我们在项目目录下的__init__.py文件中修改:

import pymysql
pymysql.install_as_MySQLdb()

技术图片

ps:如果不进行第二步代码声明,会发现Django起不来了,报错如图:

技术图片

Django之ORM简介

"""
ORM. 对象关系映射
作用:能够让一个不用sql语句的小白也能够通过python 面向对象的代码简单快捷的操作数据库
不足之处:封装程度太高 有时候sql语句的效率偏低 需要你自己写SQL语句

类                                 表

对象                               记录
    
对象属性                            记录某个字段对应的值

需要操作应用下面的models.py文件
"""

1、先去应用下的models.py中书写一个类(表)

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
   verbose_name该参数是所有字段都有的 就是用来对字段的解释,加了是有好处的
    """ 
    # password int 
    password = models.IntegerField(verbose_name="密码")

2、数据库迁移命令(特别重要)

注意:在models.py里写完是没办法直接生效的,需要告诉ORM,要把上面models.py中的操作基于ORM映射到数据库里面去

两条命令:

#*************************# 2 数据库迁移命令*************************
python3 manage.py makemigrations 将操作记录记录到小本本上(就是应用中的migrations文件夹)

python3 manage.py migrate  将操作真正的同步到数据库中
# 只要你修改了models.py中跟数据库相关的代码 就必须重新执行上述的两条命令
#******************************************************************

点击pycharm的terminal终端,在终端里面输入这两条数据库迁移命令

# python3 manage.py makemigrations 将操作记录记录到小本本上(就是应用中的migrations文件夹)

技术图片

技术图片

# python3 manage.py migrate  将操作真正的同步到数据库中

技术图片

 

 

 执行完之后再查看数据库(记得刷新之后再查看)

技术图片

 表解释:

技术图片

# app01_user表:就是我们通过ORM创建的表

#ps:
为什么会自动加个前缀app01呢?
因为一个Django项目可以有多个应用,那么多个应用之间可能会出现表名冲突的情况,加上前缀就可以完全避免,比较人性化

点开app01_user表看一看:

技术图片

补充:

1、

# 由于一张表中必须要有一个主键字段 并且一般情况下都叫id字段
# 所以orm当你不定义主键字段的时候 orm会自动帮你创建一个名为id主键字段
# 也就意味着 后续我们在创建模型表的时候如果主键字段名没有额外的叫法 那么主键字段可以省略不写

所以我们再models.py里面可以这么写:

class Author(models.Model):
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name=用户名)
    # password int
    password = models.IntegerField(verbose_name=密码)
    """
    CharField必须要指定max_length参数 不指定会直接报错
    verbose_name该参数是所有字段都有的 就是用来对字段的解释
    """

2、数据库迁移命令,也可以在Tools-Run manage.py Task...里面写

技术图片

不用写python3 manage.py,直接写命令(前期不建议使用)

如下:

# makemigrations   将操作记录记录到小本本上(应用下migrations文件夹中)

# migrate     将操作真正同步到数据库中

利用ORM实现数据的增删改查操作

字段的增删改查

先看一下环境:

user数据库:

技术图片

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    password = models.IntegerField(verbose_name="密码")

增字段

直接在models.py中的类的相应位置添加字段就可以,例如给user数据库添加一个age字段

表中已经有数据,添加字段第一种处理方法:执行# python3 manage.py migrations时出现选项后选1,立即给一个默认值

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    password = models.IntegerField(verbose_name="密码")
    age = models.IntegerField(verbose_name="年龄")

因为修改了跟数据库相关的代码,得执行一下数据库迁移命令:

# python manage.py makemigrations     # 注意:会有提示,这是因为user表中已经有数据

技术图片

第一个选项:立刻给他设置一个默认值

第二个选项:离开之后手动给他添加一个默认值

技术图片

技术图片

# python3 manage.py migrate

表中已经有数据,添加字段第二种处理方法:在models.py的类中添加字段时,设置字段可以为空

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    password = models.IntegerField(verbose_name="密码")
    age = models.IntegerField(verbose_name="年龄")
    # null=True字段可以为空
    info = models.CharField(max_length=32,verbose_name="个人简介",null=True)

此时执行数据库迁移命令,就不会出现选项了。

技术图片

技术图片

表中已经有数据,添加字段第三种处理方法:在models.py的类中添加字段时,直接给默认值

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    password = models.IntegerField(verbose_name="密码")
    age = models.IntegerField(verbose_name="年龄")
    # null=True字段可以为空
    info = models.CharField(max_length=32,verbose_name="个人简介",null=True)
    # default直接给字段设置默认值
    hobby = models.CharField(max_length=32,verbose_name="兴趣爱好",default="study")

执行数据库迁移命令

技术图片

技术图片

修改字段:直接修改代码然后执行数据库迁移的两条命令即可

修改前的password字段类型

技术图片

例如:我要把password的字段类型改成varchar类型

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")

    # password = models.IntegerField(verbose_name="密码")   #原先的
    password = models.CharField(max_length=32,verbose_name="密码")  #修改后的
    age = models.IntegerField(verbose_name="年龄")
    # null=True字段可以为空
    info = models.CharField(max_length=32,verbose_name="个人简介",null=True)
    # default直接给字段设置默认值
    hobby = models.CharField(max_length=32,verbose_name="兴趣爱好",default="study")

执行数据库迁移命令

# python3 manage.py makemigrations

# python3 manage.py migrate

修改后查看password类型

技术图片

字段的删除:把想删除的字段注释掉,然后再执行数据库迁移的两条命令即可(执行完毕之后字段对应的数据也都没有了)

比如说我想删除age,info以及hobby字段

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    # password = models.IntegerField(verbose_name="密码")   #原先的
    password = models.CharField(max_length=32,verbose_name="密码")  #修改后的
    # age = models.IntegerField(verbose_name="年龄")
    # # null=True字段可以为空
    # info = models.CharField(max_length=32,verbose_name="个人简介",null=True)
    # # default直接给字段设置默认值
    # hobby = models.CharField(max_length=32,verbose_name="兴趣爱好",default="study")

数据库迁移

# python3 manage.py makemigrations

# python3 manage.py migrate

查看

技术图片

总结:

"""
在操作models.py的时候一定要细心
    注释一些字段千万要小心,因为注释后执行迁移命令,字段对应的数据就都没了
    执行迁移命令之前最好先检查一下自己写的代码
"""

# 个人建议:当你离开你的计算机之后一定要锁屏

数据的增删改查:

看一下环境:

数据库:

技术图片

查询数据:models.User.objects.filter()

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models    # orm查询数据要依靠这个

# Create your views here.
#login
def login(request):
    """
    get请求和post请求应该有不同的处理机制,可以使用request的对象方法
    :param request:请求相关的数据对象,里面有很多简易的方法
    :return:
    """
    # print(request.method)    # request.method:返回请求方式,并且是全大写的字符串形式
    if request.method == "POST":
        #获取用户的用户名和密码 然后利用orm操作数据 校验数据是否正确
        username = request.POST.get("username")
        password = request.POST.get("password")
        
        # 去数据库中查询数据
        # select * from user where username=‘egon‘;   可以把filter联想成where记忆
        user_obj = models.User.objects.filter(username=username).first()     #拿到列表里的第一个元素
      # ps:filter()里面可以跟多个参数,用逗号隔开
        # user_obj = models.User.objects.filter(username=username,password=password).first()   #select * from user where username=‘egon‘ and password = ‘xxx‘;

        # print(res)     # <QuerySet [<User: User object>]>   类似于列表套数据对象,[数据对象1,数据对象2],它也支持索引取值,切片操作,注意不支持负数
        # user_obj = res[0]   # 但是并不推荐使用索引取值,使用models.User.objects.filter(username=username).first()
        # print(user_obj)    # 默认是打印User object,可以在models.py中对应类定制 __str__方法,打印对象时触发,见下面egon
        # print(user_obj.username)   # egon
        # print(user_obj.password)   # 123
        if user_obj:
            # 比对密码是否一致
            if password == user_obj.password:
                return HttpResponse("登录成功")
            else:
                return HttpResponse("密码错误")
        else:
            return HttpResponse("用户不存在")

    return render(request, "login.html")

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    # password = models.IntegerField(verbose_name="密码")   #原先的
    password = models.CharField(max_length=32,verbose_name="密码")  #修改后的
    # age = models.IntegerField(verbose_name="年龄")
    # # null=True字段可以为空
    # info = models.CharField(max_length=32,verbose_name="个人简介",null=True)
    # # default直接给字段设置默认值
    # hobby = models.CharField(max_length=32,verbose_name="兴趣爱好",default="study")

    def __str__(self):    #当对象被打印的时候,会触发这个方法
        return "%s" %self.username

数据的增加:

增的方法一:models.User.objects.create()

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^login/, views.login),
    url(r^register/, views.register),
]

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models  # orm查询数据要依靠这个

# Create your views here.
#login
def login(request):
    """
    get请求和post请求应该有不同的处理机制,可以使用request的对象方法
    :param request:请求相关的数据对象,里面有很多简易的方法
    :return:
    """
    # print(request.method)    # request.method:返回请求方式,并且是全大写的字符串形式
    if request.method == "POST":
        #获取用户的用户名和密码 然后利用orm操作数据 校验数据是否正确
        username = request.POST.get("username")
        password = request.POST.get("password")
        from app01 import models  # orm查询数据要依靠这个
        # 去数据库中查询数据
        # select * from user where username=‘egon‘;
        user_obj = models.User.objects.filter(username=username).first()     #拿到列表里的第一个元素
        # print(res)     # <QuerySet [<User: User object>]>   类似于列表套数据对象,[数据对象1,数据对象2],它也支持索引取值,切片操作,注意不支持负数
        # user_obj = res[0]   # 但是并不推荐使用索引取值,使用models.User.objects.filter(username=username).first()
        # print(user_obj)    # 默认是打印User object
        # print(user_obj.username)   # egon
        # print(user_obj.password)   # 123
        if user_obj:
            # 比对密码是否一致
            if password == user_obj.password:
                return HttpResponse("登录成功")
            else:
                return HttpResponse("密码错误")
        else:
            return HttpResponse("用户不存在")

    return render(request, "login.html")

#注册
def register(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        
        user_obj = models.User.objects.filter(username=username).first()
        if user_obj:
            return HttpResponse("用户已经存在")
        # 直接获取用户数据存入数据库
        res = models.User.objects.create(username=username,password=password)
        # res返回值就是当前被创建的对象本身
        print(res)  # alias,这是个对象,打印这个是因为之前在models.py对应的类里添加l__str__方法
    # 先给用户返回一个注册页面
    return render(request,"register.html")

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    # password = models.IntegerField(verbose_name="密码")   #原先的
    password = models.CharField(max_length=32,verbose_name="密码")  #修改后的
    # age = models.IntegerField(verbose_name="年龄")
    # # null=True字段可以为空
    # info = models.CharField(max_length=32,verbose_name="个人简介",null=True)
    # # default直接给字段设置默认值
    # hobby = models.CharField(max_length=32,verbose_name="兴趣爱好",default="study")

    def __str__(self):    #当对象被打印的时候,会触发这个方法
        return "%s" %self.username

增的方式二:实例化类

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models  # orm查询数据要依靠这个

# Create your views here.
#login
def login(request):
    """
    get请求和post请求应该有不同的处理机制,可以使用request的对象方法
    :param request:请求相关的数据对象,里面有很多简易的方法
    :return:
    """
    # print(request.method)    # request.method:返回请求方式,并且是全大写的字符串形式
    if request.method == "POST":
        #获取用户的用户名和密码 然后利用orm操作数据 校验数据是否正确
        username = request.POST.get("username")
        password = request.POST.get("password")
        from app01 import models  # orm查询数据要依靠这个
        # 去数据库中查询数据
        # select * from user where username=‘egon‘;
        user_obj = models.User.objects.filter(username=username).first()     #拿到列表里的第一个元素
        # print(res)     # <QuerySet [<User: User object>]>   类似于列表套数据对象,[数据对象1,数据对象2],它也支持索引取值,切片操作,注意不支持负数
        # user_obj = res[0]   # 但是并不推荐使用索引取值,使用models.User.objects.filter(username=username).first()
        # print(user_obj)    # 默认是打印User object
        # print(user_obj.username)   # egon
        # print(user_obj.password)   # 123
        if user_obj:
            # 比对密码是否一致
            if password == user_obj.password:
                return HttpResponse("登录成功")
            else:
                return HttpResponse("密码错误")
        else:
            return HttpResponse("用户不存在")

    return render(request, "login.html")

#注册
def register(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        user_obj = models.User.objects.filter(username=username).first()
        if user_obj:
            return HttpResponse("用户已经存在")
        # 实例化类
        user_obj = models.User(username=username,password=password)
        user_obj.save()  #保存数据
    # 先给用户返回一个注册页面
    return render(request,"register.html")

models.py

from django.db import models

# Create your models here.
# 类 -- 表
class User(models.Model):    # 一定要继承父类models.Model
    # id int primary auto_increment
    id = models.AutoField(primary_key=True,verbose_name="主键")  # 此句等同于设置id字段为主键并且自增的sql语句;
    # username varchar(32)
    username = models.CharField(max_length=32,verbose_name="用户名")
    """
    CharField必须要指定max_length参数,不写直接报错
    """
    # password int
    # password = models.IntegerField(verbose_name="密码")   #原先的
    password = models.CharField(max_length=32,verbose_name="密码")  #修改后的
    # age = models.IntegerField(verbose_name="年龄")
    # # null=True字段可以为空
    # info = models.CharField(max_length=32,verbose_name="个人简介",null=True)
    # # default直接给字段设置默认值
    # hobby = models.CharField(max_length=32,verbose_name="兴趣爱好",default="study")

    def __str__(self):    #当对象被打印的时候,会触发这个方法
        return "%s" %self.username

 

以上是关于Django进阶的主要内容,如果未能解决你的问题,请参考以下文章

Atom编辑器入门到精通 Atom使用进阶

Django进阶

我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段

我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段

63-Django进阶(路由系统)

Django 进阶篇二