一、表字段的增删改查
- 新增
from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) addr= models.CharField(max_length=64) # 新增addr字段
注意:对于已存在数据的表,新增字段必须要给定默认值,默认值有两种方法
如果models.py里没有指定默认值,执行python3 manage.py makemigrations时,会提示以下信息
''' D:codemylogin>python3 manage.py makemigrations You are trying to add a non-nullable field 'addr' to user without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows with a null value for this column) 2) Quit, and let me add a default in models.py '''
选择1,就是在makemigrations时添加新字段的默认值
Select an option: 1 Please enter the default value now, as valid Python The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now Type 'exit' to exit this prompt >>> 'shanghai' Migrations for 'app01': app01migrations 002_user_addr.py - Add field addr to user D:codemylogin>python3 manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying app01.0002_user_addr... OK
在models.py里指定新字段的默认值
from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) addr= models.CharField(max_length=64) phone=models.CharField(max_length=11,default='')
- 修改字段
from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) addr= models.CharField(max_length=128) # max_length=64改为28 phone_num=models.CharField(max_length=11,default='') # phone 改为phone_num
D:codemylogin>python3 manage.py makemigrations Did you rename user.phone to user.phone_num (a CharField)? [y/N] y # 对于已上线的项目 谨慎做修改字段名的操作 Migrations for 'app01': app01migrations 004_auto_20190312_1403.py - Rename field phone on user to phone_num - Alter field addr on user D:codemylogin>python3 manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying app01.0004_auto_20190312_1403... OK
- 删除字段(同理,对于已上线的项目,删除字段慎之又慎,别给自己找麻烦)
from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) addr= models.CharField(max_length=128) # phone_num=models.CharField(max_length=11,default='') # 注释就是删除
D:codemylogin>python3 manage.py makemigrations Migrations for 'app01': app01migrations 005_remove_user_phone_num.py - Remove field phone_num from user D:codemylogin>python3 manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying app01.0005_remove_user_phone_num... OK
二、单表数据增删改查
- 查询单条数据 user = models.User.objects.filter(name=name, pwd=pwd).first()
- 返回的是user对象,可以通过user.name得到属性的值
def login(request): if request.method == 'GET': return render(request, 'login.html') else: # 取出POST中携带的参数 name = request.POST.get('name') pwd = request.POST.get('pwd') if name and pwd: # 去数据库里查 user = models.User.objects.filter(name=name, pwd=pwd).first() # print(user.name,user.pwd) # user是一个实例对象 对象.属性 可获取到属性的值 if user: # user有值的情况 return redirect('https://www.baidu.com') else: return HttpResponse('用户名或密码错误') else: return HttpResponse('用户名或密码不能为空')
- 查询所有数据 ret = models.User.objects.all()
- 返回的是QuerySet对象 [<User: User object (1)>, <User: User object (2)>]
- 通过render渲染,返回给前台展示 return render(request, 'userlist.html', {'userlist': ret})
def userlist(request): # 查出 User表中的所有数据 # sql: select * from app01_user; ret = models.User.objects.all() # orm返回一个QuerySet对象django.db.models.query.QuerySet return render(request, 'userlist.html', {'userlist': ret})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>账号列表</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> </head> <h3> <a href="/useradd/">新增用户</a> </h3> <table class="table table-bordered table-responsive"> <thread> <tr> <th>id</th> <th>name</th> <th>pwd</th> <th>addr</th> <th>操作</th> </tr> </thread> <tbody> {% for user in userlist %} <tr> <td>{{ user.id }}</td> <td>{{ user.name }}</td> <td>{{ user.pwd }}</td> <td>{{ user.addr }}</td> <td> <a href="/useredit?id={{ user.id }}">修改</a> <a href="/userdel?id={{ user.id }}">删除</a> <a href="/useredit?id={{ user.id }}">修改</a> </td> </tr> {% endfor %} </tbody> </table> <body> </body> </html>
- 删除记录 先通过filter方法查出数据,再调delete方法删除之 models.User.objects.filter(id=id).delete()
- 返回的是:影响的行数
- 前端可通过get携带参数 <a href="/userdel?id={{ user.id }}">删除</a>
def userdel(request): # 取出前端传过来的id id = request.GET.get('id') ret = models.User.objects.filter(id=id).delete() print(ret, type(ret)) return redirect('/userlist/')
- 新增数据
- 方式1:models.User.objects.create(name=name, pwd=pwd, addr=addr) # 调用create()方法创建一条新纪录
- 方式2:models.User(name=name, pwd=pwd, addr=addr).save() # 先生成一个新的user对象,再调save方法保存到数据库
- 前端的form表单中的数据在post到后端时,将form表单的数据以key=value&key=value的格式打包到body里:name=lck&pwd=1234 可通过request.body拿到
def useradd(request): if request.method == 'GET': return render(request, 'useradd.html') elif request.method == 'POST': name = request.POST.get('name') pwd = request.POST.get('pwd') addr = request.POST.get('addr') if name and pwd and addr: # 方式1: create()方法创建一条新纪录 # models.User.objects.create(name=name, pwd=pwd, addr=addr) # 方式2: 先生成一个新的user对象,再调save方法保存到数据库 models.User(name=name, pwd=pwd, addr=addr).save() return redirect('/userlist/') else: return HttpResponse('用户名、密码、地址不能为空')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新增用户</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> </head> <body> <form method="post"> <div class="form-group"> <label for="name">用户名</label> <input type="text" class="form-control" name="name" placeholder="用户名"> </div> <div> <label for="pwd">密码</label> <input type="password" class="form-control" name="pwd" placeholder="密码"> </div> <div> <label for="addr">地址</label> <input type="text" class="form-control" name="addr" placeholder="地址"> </div> <button type="submit" class="btn btn-default">提交</button> </form> </body> </html>
- 修改数据 models.User.objects.filter(id=id).update(name=name,pwd=pwd,addr=addr) # 先通过前端get携带的id,调用filter方法查出对应数据,再调update方法更新
- 返回的是:影响的行数
- 后端逻辑:前端GET携带id请求,后端返回此id对应的数据,前端修改后POST提交到后端,后端完成数据更新
def useredit(request): if request.method == 'GET': id=request.GET.get('id') user=models.User.objects.filter(id=id).first() return render(request,'useredit.html',{'user':user}) else: id=request.GET.get('id') # 前端form的action的url里带了id 所以可以从GET里取出 id1=request.POST.get('id') # 前端form表单里id隐藏了,所以亦可以从POST里取出 name=request.POST.get('name') pwd=request.POST.get('pwd') addr=request.POST.get('addr') # user=models.User.objects.filter(id=id) # 查出id对应的数据,然后update新数据 # user.update(name=name,pwd=pwd,addr=addr) # 上面两行可以合并成一行 models.User.objects.filter(id=id).update(name=name,pwd=pwd,addr=addr) return redirect('/userlist/')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>修改用户信息</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> </head> <body> <h2>修改用户信息</h2> <div class="col-md-6 col-md-offset-3"> <form action="/useredit/?id={{ user.id }}" method="post"> <input type="hidden" name="id" value="{{ user.id }}" class="form-control"> <p>用户名: <input type="text" name="name" value="{{ user.name }}" class="form-control"></p> <p>密码: <input type="password" name="pwd" value="{{ user.pwd }}" class="form-control"></p> <p>地址: <input type="text" name="addr" value="{{ user.addr }}" class="form-control"></p> <input type="submit" value="提交"> </form> </div> </body> </html>