Django魔法

Posted mcc61

tags:

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

(●‘?‘●)??(●ˇ∀ˇ●)django,我来啦

在使用一个框架之前首先要了解一下这个框架不支持什么对不对~ o(* ̄▽ ̄*)o

确保django能够正确使用的前提

  1.计算机的名称不要有中文(快去看看吧!)

    此电脑--属性--计算机名--更改设置

  2.项目名不要起中文   --可能会引起冲突

  3.一个pycharm窗口不要起多个工程(项目)--都是血和泪的教训,但是说不定还会犯??

安装django

  推荐使用1.11.xx开头,在程序员的世界中求稳不求新!

方式一:命令行安装
      pip3 install django==1.11.11
    测试安装是否成功
    django-admin      --如果出现了一大堆的数据,那么显示安装成功啦
方式二:pycharm安装
    file--settings--project--选择第一个--点击右边的+--然后输入django--右下角选择你要下载的版本号(不写默认最新版哦)  

ps:其他库在pycharm中也是如此安装

 

创建django项目

方式一:命令行创建   --哎呀,这个一定要记住的啊,每次都走一遍不是吗??????
       django-admin-startproject  项目名称(是不是不应该用中文~ o(* ̄▽ ̄*)o)
方式二:pycharm创建  
      file -- new project -- django  -- Existing interpreter  -- more settings  --勾选Enable Django admin   就是如此简单!
    创建成功以后我们来low一眼里面都有哪些东西,对他们进行学习 项目文件夹
__init.py --还记得创建包的时候,出现的那个__init__.py吗,同理
settings.py
--放的是一些配置文件相关
urls.py
--放的是你的路由与视图函数的对应关系
wsgi.py
manage.py
--django的入口文件
    ps:pycharm能自动帮你创建一个app并自动注册到配置文件中
 

注意^(* ̄(oo) ̄)^:命令行创建的django项目并不会自动创建templates文件夹,需要自己手动创建并添加到settings中

TEMPLATES = [
            
                BACKEND: django.template.backends.django.DjangoTemplates,
                DIRS: [os.path.join(BASE_DIR,templates)],
                APP_DIRS: True,
                OPTIONS: 
                    context_processors: [
                        django.template.context_processors.debug,
                        django.template.context_processors.request,
                        django.contrib.auth.context_processors.auth,
                        django.contrib.messages.context_processors.messages,
                    ],
                ,
            ,
        ]

     ps:后期在使用的时候会有多个项目存在,但是切记,一个窗口只可以有一个项目在运行,而且在浏览器页面要注意清除浏览器的缓存,不然可能会出现代码已经改变了,但是效果并没有变

    清除浏览器缓存的方法 --嘿嘿,必须上图片啊!

    技术图片

      

接下来就要创建应用,也就是app,创建之前我们先得了解什么是app?

你可以这么理解

  整个django项目就是一所牛逼的大学,一个个的app就是牛逼大学里面的一个个牛逼的学院,一个个的学院支撑起了整个大学,也就是django是由一个个的app支撑着的

  django:综合性的大学

  app:大学里面的学院

创建django应用之app

方式一:命令行创建
  python3(选择你的python解释器) manage.py startapp 应用名
方式二:pycharm创建
      pycharm命令行中
            python3 manage.py startapp app01
      Tools中
            run manage.py Task 中startapp app02

应用下的文件夹

__init__.py  
admin.py          django后台管理
modles.py         模型表
views.py          所有的视图函数
注意你新建的app需要在配置文件中注册
INSTALLED_APPS = [
                django.contrib.admin,
                django.contrib.auth,
                django.contrib.contenttypes,
                django.contrib.sessions,
                django.contrib.messages,
                django.contrib.staticfiles,
                app01.apps.App01Config
            ]
        

启动和停止django的命令

方式一:命令行
        启动:python3 manage.py runserver
        停止:ctrl + c
方式二:pycharm中
        启动:小绿色箭头
        停止:红色方块

补充一点:修改默认的8000端口,如果没有可以自己重新创建一个,+号就可以

                                      技术图片

 

正式开始学习django这个强大的框架吧????????????

1.django小白必会三板斧

from django.shortcuts import render,HttpResponse,redirect     在你的views.py中导入

HttpResponse  返回字符串
render        返回一个html页面并且支持模板渲染
    两种给前端页面传值的方式
        def reg(request):
            user_dict = name:jason,password:123
            return render(request,reg.html,user_dict:user_dict)
        
        def reg(request):
            user_dict = name:jason,password:123
            return render(request,reg.html,locals())
            
redirect      重定向

2.基于登录功能实现对orm,pycharm连接数据库的学习

2.1首先来学习一个小的知识点

技术图片

这是敲完回车之后的结果!

 

技术图片

看到了这里估计你以为是浏览器自动给我们补上了这个/,其实也没错,只不过浏览器并不是直接补上了这个/,而是在先向服务端将这个请求发过去,服务端没找到,回复浏览器,你要不重新加上一个/给我,我再试试,然后浏览器再次发送的时候加上了一个/,就成功了,注意,如果这次还匹配不上,那就报错了╮(╯_╰)╭

看图说话?????? 事实胜于雄辩

技术图片

2.2静态文件

添加静态文件(css,js,前端第三方类库)到static文件夹下

技术图片

添加完静态文件以后我们就可以愉快的敲代码了,然后也可以实现我们想要的页面了

技术图片

但是,我们并没有实现我们想要的结果!!!这是为什么捏?

技术图片

问问自己静态文件的环境变量你配置了吗,难道计算机可以人工智能的帮你配吗??????

静态文件的配置

静态文件配置
STATIC_URL = /static/
# 静态文件配置
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,static)
]
# 暴露给外界能够访问服务器静态文件夹下面所有的资源


STATIC_URL = /xxx/  # 接口前缀 跟你的静态文件夹的名字一点关系都没有
# 默认情况下这个前缀跟静态文件夹名字一样!!!
# 静态文件配置
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,static),  # 就是你的静态文件夹路径
    os.path.join(BASE_DIR,static1),
    os.path.join(BASE_DIR,static2)
]
#ps:会依次查找列表中所有的静态文件路径 找到的话立刻停止,都没有找到返回404

 嗯,现在就很nice,配置好了

2.3 form表单提交数据的地址及指定方式

action属性控制提交的地址
    方式:
        1.全路径
            <form action="http://127.0.0.1:8000/login/">
        2.只写路径后缀
            <form action="/login/">
        3.不写 (默认往当前路径提交)
    form表单默认是get请求

2.4 登录功能的实现

  1.拿到浏览器发给你的数据 2.去数据库中找到对应的数据进行匹配 3.匹配成功返回浏览器登录成功的消息

import pymysql
def login(request):
    if request.method==POST:  
        # print(request.POST)
        username=request.POST.get(username)
        password=request.POST.get(password)
        conn=pymysql.connect(
            host=127.0.0.1,
            port=3306,
            user=root,
            password=123,
            charset=utf8,
            database=day54,
            autocommit=True
        )
        cursor=conn.cursor(pymysql.cursors.DictCursor)
        cursor.execute("select * from user where name=%s and password=%s", (username,password))
        res=cursor.fetchall()
        if res:  #[,,]
            # return render(request,‘login.html‘,locals())
            return HttpResponse(登录成功!)
    return render(request,login.html)

看到这里有没有疑惑,一顿操作猛如虎,结果看不懂

详细解释看下方

根据客户端请求方式的不同执行不同的逻辑代码
    def login(request):
        # 获取用户端提交的请求方式
        print(request.method)  # 拿到的请求方式是全大写的字符串
        if request.method == GET:
            return render(request,login.html)
        elif request.method == POST:
            return HttpResponse("收到了 老弟")

 个人建议按照下面这种方式书写 减少代码冗余及结构混乱的问题
    def login(request):
        if request.method == POST:
            return HttpResponse(OK)
        return render(request,login.html)

这是取到的数据的具体解释

def login(request):
    # 获取用户端提交的请求方式
    print(request.method)  # 拿到的请求方式是全大写的字符串
    # if request.method == ‘GET‘:
    #     return render(request,‘login.html‘)
    # elif request.method == ‘POST‘:
    #     return HttpResponse("收到了 老弟")
    if request.method == POST:
        print(request.POST)  # 你就把它当成一个大字典里面存放了客户端post提交的所有的数据
        # request.POST:< QueryDict: ‘username‘: [‘jason‘], ‘password‘: [‘123‘] >
        print(request.POST.get(username))  # value虽然是个列表但是获取value的时候拿到却是单个元素
        # 默认只会取value列表里面的最后一个元素
        # request.POST:<QueryDict: ‘username‘: [‘jason‘, ‘egon‘], ‘password‘: [‘123‘]>
        print(request.POST.getlist(username))  # 要想一次性获取value列表里面所有的数据需要用getlist()
        # [‘jason‘, ‘egon‘]
        print(request.POST[password])  # 不推荐使用该方法获取数据
        return HttpResponse(OK)
    return render(request,login.html)

    获取value列表里面所有的元素需要使用getlist  应用场景:用户的爱好 多选框
    get只会获取到value列表的最后一个元素

    print(request.GET)  # <QueryDict: ‘username‘: [‘jason‘], ‘password‘: [‘123‘]>
    request.GET.get(user)
    # <QueryDict: ‘username‘: [‘jason‘,‘egon‘], ‘password‘: [‘123‘]>
    request.GET.getlist(username)

html页面内容展示     

form表单默认的提交方法是GET,我们这里需要将这个请求方法变成POST,注意全部大写

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <p>登录页面</p>
        <form action="/login/" class="col-md-8 col-xs-offset-2" method="POST">
            <p>username:<input type="text" class="form-control" name="username"></p>
            <p>password:<input type="text" class="form-control" name="password"></p>
            <input type="submit" class="btn btn-success">
        </form>
    </div>
</div>
</body>
</html>

2.5 pycharm实现数据库连接

上面是我们自己直接调用pymysql实现的登录功能,记住,只要涉及到了重复调用一定是有东西可以帮我们实现的

1.需要修改配置文件
        DATABASES = 
            default: 
                ENGINE: django.db.backends.mysql,
                NAME: day54,  #这里的NAME指代的就是database
                HOST:127.0.0.1,
                PORT:3306,
                USER:root,
                PASSWORD:123‘   #不用写自动提交和编码
            
        
        ps:键必须都是大写  

    2.告诉django用pymysql替换它默认mysqldb模块连接数据库
        方式1:在你的项目文件夹下面的__init__.py
        方式2:也可以在你的应用文件夹下面的__init__.py

        # 固定写法
        import pymysql
        pymysql.install_as_MySQLdb()  # 告诉django用pymysql代替mysqldb连接数据库

什么是ORM?

     对象关系映射
类 》》》 表
对象 》》》 表记录
对象的属性 》》》 一条记录某个字段对应的值
django的orm不能够自动帮你创建库,但是可以自动帮你创建表
提示:一个django项目就使用一个库,不要多个django项目使用一个库

新建完数据库以后就可以新建表了,每一个表新建好以后要去models里面建立映射关系表,然后执行数据库迁移(同步)命令********记住,只要涉及到了数据库中字段的操作都要去执行命令

python3 manage.py makemigrations  将你的数据库变动记录到一个小本本上(并不会帮你创建表)
python3 manage.py migrate         将你的数据库变动正在同步到数据库中

2.6 数据库orm操作

新增数据

#新增数据
#操作数据库user表插入数据
#方式一:
user_obj=models.User.object.create(name=username,password=password)
#方式二:
user_obj=models.User(name=username,password=password)
user_obj.save()

查询数据

user_list=models.User.object.all()  # 获取user表所有的数据
#只要是QuerySet就可以点query查看获取到当前QuerySet对象的内部sql语句
print(user_list.query)

删除数据

models.User.object.filter(id=1).delete()   # 会将queryset所有的数据对象全部删除

修改数据

#先根据浏览器传过来的信息拿到要修改的那条数据
#然后将查到的这条数据展示给用户看
#用户点击提交按钮之后再将数据修改成功
#返回给用户修改成功后的页面

  1.那么如果来做呢?首先我们如何获取id的来源,一共两种方式

#编辑对象的id的获取方式
方式一:利用input隐藏一个标签
 <input type="hidden" name="edit-id" value="user_obj.pk">
方式二:
<form action="/edit/?edit_id=user_obj.pk" method="POST">

  2.利用拿到的数据查询到当前的数据,也是两种方式

#方式一:
models.User.object.filter(id=edit_id).first()
#方式二:
user_obj=models.User.object.get(id=edit_id)  # 用get可以直接获取到数据对象本身但是查询条件不存在的情况下会报错

  3.将查询到的数据返回给用户看--也就是跳到编辑页面??????

#编辑对象的id的获取方式
方式1:利用input隐藏一个标签
<input type="hidden" name="edit_id" value=" user_obj.pk ">
方式2:
<form action="/edit/?edit_id= user_obj.pk " method="post">

  4.进行数据的修改

#方式一:
models.User.object.filter(id=edit_id).update(name=username,password=password)
#方式二:
user_obj=models.User.object.filter(id=edit_id).first()
user_obj.name=username
user_obj.save()

注意啦,划重点啦

只要是修改了模型表里面的和表相关的所有数据,只要你修改了就必须重新执行数据库迁移命令

python3 manage.py makemigrations    # 记录到小本本上
python3 manage.py migrate                # 真正操作数据库

示例:

明天再修改吧,改不动了

  

 

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

如何使用魔法来验证 Django 表单清理方法中的文件类型?

Django --魔法方法:def __str__()

js兵器谱之魔法召唤师:call / apply

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

通过django中间件和python魔法方法实现自定义session(通过文件存储session)

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段