Django ORM 增删改查


目录
  • Django ORM
  • 如何操作?应用下的models.py。
  • 先在 App01/models.py 书写一个类
  • 数据库迁移命令(重要)
  • 利用ORM实现字段的增删改查
    • 增加
    • 字段的修改
    • 字段的删除
  • 数据的增删改查
    • 数据的查询,客户端输入姓名和密码,服务端前往数据库比对,如果用户输入姓名数据库表中无记录返回None。>>> filter
    • 数据的增加,比如客户端注册: models.User.objects.create(username=username,password=password),直接获取用户数据存入数据库,返回值就是被创建对象本身。
    • 第一种
    • 第二种:利用对象点属性
  • 编辑功能
    • 思路:
    • 如何操作?,/edit_user/
    • 那么如何确认用户编辑哪条数据?主键,user_id={{ user_obj.id }}。
    • 获取到主键之后加入判断
        • 修改数据并更新方式1: models.User.objects.filter(id=edit_id).update(username=username)
          • 方法特性:将filter查询出来的列表中所有的对象全部更新,批量更新操作,只修改被修改的字段。
        • 修改数据并更新方式2: 通过对象点的方式
          • 方法特性:当字段特别多的时候效率非常低,从头到尾将数据的所有字段全部更新一遍,无论该字段是否被修改。
    • 记录的新增,与修改差异不大
    • 记录的删除

Django ORM

ORM : 对象关系映射

作用 : 能够让一个不用sql语句的小包也能通过python,面向对对象的代码简单快捷操作数据库。

不足之处 : 封装程度太高,优势sql语句的效率偏低,需要自己写sql语句。

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

如何操作?应用下的models.py。

先在 App01/models.py 书写一个类

from django.db import models

# Create your models here.
class User(models.Model):
    """
    创建一个id字段,并且是自增
    等同于:id int primary key auto_increment
    """
    id = models.AutoField(primary_key=True)
    """
    username varchar(32)
    """
    username = models.CharField(max_length=32)
    """
    password int
    """
    password = models.IntegerField()

写完之后并不会直接生效

数据库迁移命令(重要)

打开pycharm中的命令行

将操作记录记录到migrations文件夹

python3 manage.py makemigrations

将操作同步至数据库

python3 manage.py migrate

成功之后:

可以看到,多出一个app01_user ,是我们利用orm创建的表,因为一个项目可以有多个应用,那么多个应用之间可能会出现表名冲突,奖赏前缀可避免。

总结;之哟啊修改了models.py中跟数据库相关的代码,就必须重新执行上述代码。

并且django框架可以在使用时若不自定义主键,orm将自动创建一个名为id主键字段

举例:

class Author(models.Model):
    """
    一张表必须要有一个主键,并且一般情况下都会称之为id字段
    orm在不定义主键字段时,将会自动创建一个名为id主键字段
    """
    username = models.CharField(primary_key=True)
    password = models.IntegerField()

App01/models.py:

from django.db import models


# Create your models here.
class User(models.Model):
    """
    创建一个id字段,并且是自增
    等同于:id int primary key auto_increment
    """
    id = models.AutoField(primary_key=True,verbose_name='主键')
    """
    username varchar(32)
    CharField()必需要指定max_length参数,不指定会报错
    """
    username = models.CharField(max_length=32,verbose_name='用户名')
    """
    password int
    """
    password = models.IntegerField(verbose_name='密码')

利用ORM实现字段的增删改查

增加

针对表中已有字段名,需要后续添加字段情况。

class User(models.Model):
    """
    创建一个id字段,并且是自增
    等同于:id int primary key auto_increment
    """
    id = models.AutoField(primary_key=True,verbose_name='主键')
    """
    username varchar(32)
    CharField()必需要指定max_length参数,不指定会报错
    
    """
    username = models.CharField(max_length=32,verbose_name='用户名')
    """
    password int
    """
    password = models.IntegerField(verbose_name='密码')
    # 该字段为空
    age = models.IntegerField(verbose_name='年龄',null=True)
    # 设置字段默认值
    hobby = models.CharField(max_length=32,default='丝袜',verbose_name='兴趣爱好')

注意:只要更改了models.py,必须执行python3 manage.py makemigrations 和 python3 manage.py migrate

字段的修改

直接修改代码,在执行python3 manage.py makemigrations 和 python3即可。

字段的删除

直接注释不需要的代码,在执行python3 manage.py makemigrations 和 python3即可。执行完毕之后字段对应的数据消失。

数据的增删改查

数据的查询,客户端输入姓名和密码,服务端前往数据库比对,如果用户输入姓名数据库表中无记录返回None。>>> filter

djangoday02/app01/views.py

from django.shortcuts import render, HttpResponse, redirect


# Create your views here.
# 视图函数必须接收一个形参(request)
def login(request):
    """
    get请求和post请求应该有不同的处理机制
    get请求只需获取页面
    post请求获取用户数据
    :param request:
    :return:
    """
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 查数据需要借助于类,去数据库查询数据
        from app01 import models
        res = models.User.objects.filter(username=username)
        """
        对应的sql语句: select * from user where username='junjie';
        ]> [数据对象1,数据对象2...]
        如何取值? 既然是列表,可以使用索引取值
        """
        user_obj = res[0]
        print(user_obj)
        print(user_obj.username)
        print(user_obj.password)

djangoday02/app01/models.py

from django.db import models

# Create your models here.
class User(models.Model):
    """
    创建一个id字段,并且是自增
    等同于:id int primary key auto_increment
    """
    id = models.AutoField(primary_key=True,verbose_name='主键')
    """
    username varchar(32)
    CharField()必需要指定max_length参数,不指定会报错
    
    """
    username = models.CharField(max_length=32,verbose_name='用户名')
    """
    password int
    """
    password = models.IntegerField(verbose_name='密码')
    # 该字段为空
    age = models.IntegerField(verbose_name='年龄',null=True)
    # 设置字段默认值
    hobby = models.CharField(max_length=32,default='丝袜',verbose_name='兴趣爱好')

    # 当对象被打印时,会触发此方法
    def __str__(self):
        return '%s' % self.username

输出:

junjie
junjie
111

但是不推荐使用此方法,推荐使用。

from app01 import models
				# 对应的sql语句: select * from user where username='junjie';
        user_obj = models.User.objects.filter(username=username).first()

举例:

    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 查数据需要借助于类,去数据库查询数据
        from app01 import models
        user_obj = models.User.objects.filter(username=username).first()
        # print(res)
        """
        对应的sql语句: select * from user where username='junjie';
        ]> [数据对象1,数据对象2...]
        如何取值? 既然是列表,可以使用索引取值
        """
        if user_obj:
            if password == user_obj.password:
                return HttpResponse('登录成功')
            else:
                return HttpResponse('用户名或者密码错误')
        else:
            return HttpResponse("用户并不存在")
    return render(request, 'login.html')

数据的增加,比如客户端注册: models.User.objects.create(username=username,password=password),直接获取用户数据存入数据库,返回值就是被创建对象本身。

第一种

djangoday02/urls

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 自定义对应关系,路由与视图函数对应关系
    # 登录功能
    url(r'^login/',views.login),
    # 注册功能
    url(r'^register/',views.reg)

]

djangoday02/models.py

from django.db import models


# Create your models here.
class User(models.Model):
    """
    创建一个id字段,并且是自增
    等同于:id int primary key auto_increment
    """
    id = models.AutoField(primary_key=True,verbose_name='主键')
    """
    username varchar(32)
    CharField()必需要指定max_length参数,不指定会报错
    
    """
    username = models.CharField(max_length=32,verbose_name='用户名')
    """
    password int
    """
    password = models.IntegerField(verbose_name='密码')
    # 该字段为空
    age = models.IntegerField(verbose_name='年龄',null=True)
    # 设置字段默认值
    hobby = models.CharField(max_length=32,default='丝袜',verbose_name='兴趣爱好')

    # 当对象被打印时,会触发此方法
    def __str__(self):
        return '%s' % self.username

djangoday02/views.py

def reg(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_reg = models.User.objects.create(username=username,password=password)
        print(user_reg,user_reg.username,user_reg.password)
    return render(request,'register.html')

djangoday02/register.html




    
    Title
    
    
    



注册

username:

password:

客户端填写姓名和密码之后,服务端链接的MySQL中可查询到用户的注册信息。

第二种:利用对象点属性

def reg(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_reg = models.User(username=username,password=password)
        # 保存数据
        user_reg.save()
    return render(request,'register.html')

数据的展示:MySQL数据展示

app01/views.py

def userlist(request):
    user_queryset = models.User.objects.all()
    return render(request,'userlist.html',locals())

templates


{{ user_queryset }}

那么如何展示MySQL表中数据?

templates/userlist.html




    
    Title
    
    
    



数据展示

{% for user_obj in user_queryset %} {% endfor %}
ID username password action
{{ user_obj.id }} {{ user_obj.username }} {{ user_obj.password }} {{ user_obj.password }} 编辑 删除

编辑功能

功能需求:点击编辑按钮,重定向编辑界面,编辑用户名和密码,点击编辑按钮数据保存,重定向数据展示页面展示修改后的数据。

思路:

点击编辑按钮向后端发送编辑数据请求
那么如何告诉后端客户端需要编辑的是哪条数据?或者说是需要编辑哪个ID用户数据?
# 答: 将编辑按钮所在的哪一行数据主键值发送给后端

如何操作?,/edit_user/

先操作用户点击编辑按钮重定向另一个页面,a标签href为edit_user,意味着用户点击编辑按钮会向edit_user发送get请求,并执行edit_user视图函数代码逻辑。


  编辑
  删除

template/userlist.html


数据展示

{% for user_obj in user_queryset %} {% endfor %}
ID username password action
{{ user_obj.id }} {{ user_obj.username }} {{ user_obj.password }} {{ user_obj.password }} 编辑 删除

views.py

def edit_user(request):
    return HttpResponse('哈哈')

此时,用户点击编辑按钮,页面跳转展示哈哈字样。

那么如何确认用户编辑哪条数据?主键,user_id={{ user_obj.id }}。

数据的主键值可以唯一标识一条数据,将编辑按钮所在的一行数据的主键值发送给后端即可,那么怎么向后端发送主键?。url ?后参数不参与路由匹配。


  编辑
  删除

此时查看url?后缀。

点击编辑按钮:http://127.0.0.1:8008/edit_user/?user_id=1

获取到主键之后加入判断

修改数据并更新方式1: models.User.objects.filter(id=edit_id).update(username=username)
方法特性:将filter查询出来的列表中所有的对象全部更新,批量更新操作,只修改被修改的字段。
def edit_user(request):
    # 获取url问号后面的参数
    edit_id = request.GET.get('user_id')
    print(edit_id)
    # 拿到列表内真正数据
    edit_obj = models.User.objects.filter(id=edit_id).first()
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        models.User.objects.filter(id=edit_id).update(username=username)
        
        return redirect('/userlist/')
    # 将数据对象展示到页面上
    return render(request,'edit_user.html',locals())
修改数据并更新方式2: 通过对象点的方式
方法特性:当字段特别多的时候效率非常低,从头到尾将数据的所有字段全部更新一遍,无论该字段是否被修改。
def edit_user(request):
    # 获取url问号后面的参数
    edit_id = request.GET.get('user_id')
    print(edit_id)
    # 拿到列表内真正数据
    edit_obj = models.User.objects.filter(id=edit_id).first()
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        
        edit_obj.username = username
        edit_obj.password = password
        edit_obj.save()
        
        return redirect('/userlist/')
    # 将数据对象展示到页面上
    return render(request,'edit_user.html',locals())

记录的新增,与修改差异不大

def edit_up(request):
    edit_id = request.GET.get('user_id')
    # print(edit_id)
    edit_obj = models.User.objects.filter(id=edit_id).first()
    print(edit_obj)
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        models.User.objects.create(username=username, password=password)
        return redirect('/userlist/')
    return render(request,'edit_user.html',locals())

记录的删除

def edit_delete(request):
    edit_id = request.GET.get('user_id')
    edit_obj = models.User.objects.filter(id=edit_id).delete()
    return redirect('/userlist/')