当前位置: 首页 > news >正文

Django 之 orm操作

静态文件配置

所有的html文件默认都写在templates文件夹下
所有的静态文件(css,js,前端第三方类库)默认都放在static文件夹下
html页面引入外部资源的方式:cdn、本地

静态文件配置

  STATIC_URL:
  和静态文件夹的名字没有关系
  默认情况下这个前缀跟静态文件夹名字一样!!!
  html文件head导入的本地数据,以此前缀开头,否则无法实现相应的效果

  STATICFILES_DIRS:
  暴露给外界能够访问服务器静态文件夹下面所有的资源

  会依次查找列表中所有的静态文件路径,找到立刻停止,都没有找到返回404
STATIC_URL = '/static/'  # 接口前缀# 静态文件配置
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')  # 静态文件夹路径
    os.path.join(BASE_DIR,'static1'),
]
 

登录功能

1. 路由访问

路由访问如果不加斜杠,会内部自动重定向加斜杠的路由

form表单触发提交数据的动作两种方式:

<input type="submit">
<button></button>

 

2. form表单

1)form提交数据的地址如何指定及方式?
  action属性控制提交地址的方式:

 1.全路径
<form action="http://127.0.0.1:8000/login/">

 2.只写路径后缀
<form action="/login/">

 3.不写 (默认往当前路径提交)

2)form表单默认提交方式:get请求
  若将from表单的 method='post',运行时出现以下页面:

  

将settings文件内的该中间键注释掉即可:

  

3. 后端数据处理

  根据客户端请求方式的不同执行不同的逻辑代码
  获取用户端提交方式:request.method
  当提交方式为 POST:request.POST 得到的结果,类似于一个字典里存放了客户端post提交的所有数据
  获取请求方式的两种表达方式:
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')

  request.POST 的取值方式:

def login(request):
    if request.method == 'POST':
        print(request.POST)  # <QueryDict: {'username': ['Tom'], 'password': ['123']}>
        print(request.POST.get('username'))  # Tom, value虽然是个列表,但是默认获取到value列表的最后一个元素
        print(request.POST.getlist('username'))  # ['Tom', 'Bob'] 要想一次性获取value列表里面所有的数据需要用getlist()(多个爱好)
        print(request.POST['password'])  # 123 不推荐使用该方法,取不到时会报错
        return HttpResponse("OK")
    return render(request, 'login.html')

  request.GET 的取值方式和request.POST 完一样

4. 基于pymysql完成登录功能

from django.shortcuts import render, HttpResponse, redirect
import pymysql


def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        conn = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            database='initial',
            password='123',
            charset='utf8',
            autocommit=True
        )
        cursor = conn.cursor(pymysql.cursors.DictCursor)
        cursor.execute('select * from user where name=%s and password=%s', (username, password))
        userinfo = cursor.fetchall()
        if userinfo:
            return HttpResponse('登录成功!')
    return render(request, 'login.html')    
<!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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1>登录页面</h1>
        <div class="col-md-4 col-md-offset-4">
            <form action="/login/" 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">
            </form>
        </div>
    </div>
</div>
</body>
</html>
login.html

django连接数据库 

django默认自带一个小型数据库:sqlite3,可以用来做本地测试

1. 连接MySQL,修改配置文件:键必须大写

2. 告诉django 用pymysql 替换默认的db.sqlite3,连接数据库:

方式1:项目文件夹下__init__.py

方式2:应用文件夹下__init__.py

import pymysql
pymysql.install_as_MySQLdb()
# 告诉django用pymsql代替db.sqlite3连接数据库

django 的 orm

1. 关于django的orm

不能创建库,但是可以创建表

注意:一个django项目使用一个库

创建的表的表名:“app应用名_”作为前缀名,避免多个app应用的表重名

数据库迁移(同步)命令****** 

1. 命令1:在应用下migrations中,自动生成迁移记录"编号_库名.py"

2. 命令2:在数据库中生成表"应用名_表名",及django运行时需要用到相应表

eg:django_session记录用户的登录记录....

python3 manage.py makemigrations  # 数据库变动记录(并不会创建表)

python3 manage.py migrate  # 将数据变动同步到数据库中

1)app01 > models.py 创建表 > 类

from django.db import models


class User(models.Model):
    id = models.AutoField(primary_key=True)  # 设置为主键字段
    name = models.CharField(max_length=32)  # CharField定义时必须加max_length参数
    password = models.CharField(max_length=32)

2)在Terminal中使用数据库迁移命令

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

注意:添加新字段,需设置default值

from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.AutoField(primary_key=True, serialize=False)),
                ('name', models.CharField(max_length=32)),
                ('password', models.CharField(max_length=32)),
            ],
        ),
    ]
自动生成的迁移记录:0001_initial.py

 2.django 版本注册功能

先将注册函数?添加到urls.py的urlpatterns列表中:

url(r'^reg/', views.reg),

新增数据
def reg(request):
    if request.method == 'POST':
        username = request.POST.get('username')  # 获取用户输入的用户名
        password = request.POST.get('password')
        # 操作数据库user表插入数据
        # 方式1:
        # user_obj = models.User.objects.create(name=username, password=password)
        # 方式2:
        user_obj = models.User(name=username, password=password)
        user_obj.save()  # 对象调用save方法保存到数据库
        print(user_obj.pk)  # pk获取主键字段对应的值 不管主键叫什么名字
        print(user_obj.name)  # 获取用户输入的name
        print(user_obj.password)  # 获取用户输入的password
        return HttpResponse("注册成功")

    return render(request, 'reg.html')
<!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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1>注册页面</h1>
        <div class="col-md-4 col-md-offset-4">
            <form action="" method="post">
                <p>username:<input type="text" name="username" class="form-control"></p>
                <p>password:<input type="password" name="password" class="form-control"></p>
                <input type="submit" class="btn btn-success">
            </form>
        </div>
    </div>
</div>
</body>
</html>
reg.html

 3. orm 查询数据库信息

注意:只要是QuerySet对象,就可以.query查看获取它的内部sql语句

先将注册函数?添加到urls.py的urlpatterns列表中:

url(r'^userlist/', views.userlist),
查询数据
def userlist(request):
    # 获取数据库数据
    user_list = models.User.objects.all()  # 获取user表所有的数据
    print(user_list.query)  # select * from user;得到select语句相关内容
    for user_obj in user_list:
        print(user_obj.pk, user_obj.name)  # 得到id name
    return render(request, "userlist.html", locals())

4. orm编辑删除数据

1)a标签的href属性

可以指定页面跳转的路径:可以写全路径,但推荐写后缀
注意:路径的书写一定要加斜杠,不然会在地址栏出叠加而无法跳转


2)QuerySet对象

一个存放数据对象的列表的集合,可为空<QuerySet []> <class 'django.db.models.query.QuerySet'>


? 可以获取QuerySet对象的操作:

models.User.objects.all()            User表的所有数据
models.User.objects.filter(**kwargs)  符合filter条件的数据

 

? QuerySet 对象的方法:

.query            查看内部sql语句的功能

.first()          获取第一个数据对象,无值返回None

.delete()         删除所有数据对象

.update(**kwargs)   修改所有数据对象的属性

[number]          支持索引取值,但无值会报错

 

? 注意:QuerySet对象 & models.User.objects.get(**kwargs)
  get可以直接获取到数据对象本身,但是查询条件不存在的情况下直接报错

 

数据对象的修改:

user_obj = models.User.objects.filter(id=edit_id).first()

user_obj.name = username

user_obj.save()


  

3)编辑对象的id

获取方式1:利用input隐藏一个标签

获取方式2:以get方式携带参数

方式1:
 <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> 

方式2:
<form action="/edit/?edit_id={{ user_obj.pk }}" method="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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1>展示数据</h1>

        <div class="col-md-8 col-md-offset-2">
            <a href="/reg/" class="btn btn-success">添加数据</a>
            <table class="table-hover table table-bordered table-striped">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>password</th>
                        <th>action</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user_obj in user_list %}  {# user_list = [obj1,obj2,obj3] #}
                        <tr>
                            <td>{{ user_obj.pk }}</td>
                            <td>{{ user_obj.name }}</td>
                            <td>{{ user_obj.password }}</td>
                            <td>
                                <a href="/edit/?edit_id={{ user_obj.pk }}" class="btn btn-primary">编辑</a>
                                <a href="/delete_user/?delete_id={{ user_obj.pk }}" class="btn btn-danger">删除</a>
                            </td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>
userlist.html
<!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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1>编辑数据</h1>
        <div class="col-md-6 col-md-offset-3">
            <form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
                <input type="hidden" name="edit_id" value="{{ user_obj.pk }}">
                <p>username:<input type="text" name="username" value="{{ user_obj.name }}" class="form-control"></p>
                <p>password:<input type="password" name="password" value="{{ user_obj.password }}" class="form-control"></p>
                <input type="submit" class="btn btn-warning">
            </form>
        </div>
    </div>
</div>
</body>
</html>
edit.html
def delete_user(request):
    delete_id = request.GET.get('delete_id')
    models.User.objects.filter(id=delete_id).delete()
    return redirect('/userlist/')


def edit(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        edit_id = request.POST.get('edit_id')  # 获取id的方式,由edit.html页面的提交方式决定
        edit_id = request.GET.get('edit_id')
        # 更新数据库
        models.User.objects.filter(id=edit_id).update(name=username, password=password)
        return redirect('/userlist/')
    edit_id = request.GET.get('edit_id')  # 获取要修改的数据id
    # 将查到的数据渲染到一个编辑数据
    # 查询数据方式1:
    user_obj = models.User.objects.filter(id=edit_id).first()
    # 查询数据方式2:不推荐
    # user_obj = models.User.objects.get(id=edit_id)
    return render(request, "edit.html", locals())

 

转载于:https://www.cnblogs.com/zhouyongv5/p/10986776.html

相关文章:

  • 单链表的逆转
  • 坑爹的 Java 可变参数,把我整得够惨。。
  • day25-2 random,os,sys模块
  • 文件传输协议介绍
  • 前端开发者必备的 Nginx 知识
  • WebSocket Client连接AspNetCore SignalR Json Hub
  • 精读vue-hooks
  • 扩展SpringMVC以支持更精准的数据绑定1
  • 如何安装部署秋色园QBlog站点
  • Myeclipse优化配置
  • 转换流、缓冲流、流的操作规律
  • TypeScript 学习总结 函数 接口 (二)
  • javaweb期末项目-stage3-项目测试和发布
  • RabbitMQ安装配置-01
  • JDBC详解
  • 「面试题」如何实现一个圣杯布局?
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • eclipse(luna)创建web工程
  • ES6之路之模块详解
  • Git初体验
  • iOS小技巧之UIImagePickerController实现头像选择
  • Java多线程(4):使用线程池执行定时任务
  • java小心机(3)| 浅析finalize()
  • JS题目及答案整理
  • leetcode386. Lexicographical Numbers
  • Redis 懒删除(lazy free)简史
  • redis学习笔记(三):列表、集合、有序集合
  • Theano - 导数
  • 规范化安全开发 KOA 手脚架
  • 简单基于spring的redis配置(单机和集群模式)
  • 盘点那些不知名却常用的 Git 操作
  • 如何学习JavaEE,项目又该如何做?
  • 使用common-codec进行md5加密
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #100天计划# 2013年9月29日
  • (三)Honghu Cloud云架构一定时调度平台
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (顺序)容器的好伴侣 --- 容器适配器
  • (四) 虚拟摄像头vivi体验
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET 依赖注入和配置系统
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .net反编译工具
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • @DataRedisTest测试redis从未如此丝滑
  • [c]扫雷
  • [CISCN 2019华东南]Web11
  • [Delphi]一个功能完备的国密SM4类(TSM4)[20230329更新]
  • [ffmpeg] av_opt_set 解析
  • [HarekazeCTF2019]encode_and_encode 不会编程的崽