Django ORM(Object Relational Mapping)是Django框架的核心组件之一,它让开发者用面向对象的方式操作数据库,无需直接编写SQL语句。ORM将Python类映射为数据库表,类的属性映射为字段,类的实例映射为表中的一行记录。这种设计使得Django项目可以轻松切换数据库后端(如MySQL、PostgreSQL、SQLite等),只需修改配置文件中的数据库引擎即可。
## 定义模型与生成表
以用户信息管理为例,首先在应用的 models.py 中定义Person模型:
- from django.db import models
- class Person(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=32, null=False, unique=True)
- age = models.IntegerField()
- birthday = models.DateField() # 日期,YYYY-MM-DD格式
- def __str__(self):
- return 'name:{}'.format(self.name)
- class Meta:
- db_table = 'person' # 指定数据库表名
复制代码
模型中定义的自增主键id、字符串字段name、整数字段age、日期字段birthday,都是Django ORM支持的常用字段。执行迁移命令即可在数据库中生成对应的“person”表:
- python manage.py makemigrations
- python manage.py migrate
复制代码
## 新增记录(Create)
新增操作有两种常见写法:使用create()方法或先实例化再save()。
### 方法一:类名.objects.create()
- models.Person.objects.create(name=usrname, age=age, birthday=bir)
复制代码
### 方法二:实例化后save()
- obj = models.Person(name=usrname, age=age, birthday=bir)
- obj.save()
复制代码
在视图函数 add_person 中处理POST请求,获取表单数据并写入数据库:
- def add_person(request):
- if request.method == 'POST':
- usrname = request.POST.get('username')
- age = request.POST.get('age')
- bir = request.POST.get('bir')
- # 保存到数据库
- models.Person.objects.create(name=usrname, age=age, birthday=bir)
- return redirect('/app01/all_person/')
- return render(request, 'app01/add_person.html')
复制代码
对应的模板 add_person.html 包含一个POST表单,需添加{% csrf_token %}防止跨站请求伪造:
- <!DOCTYPE html>
- <html>
- <head><meta charset="UTF-8"><title>添加用户</title></head>
- <body>
- <form action="/app01/add_person/" method="post">
- {% csrf_token %}
- <p>用户名: <input type="text" name="username"></p>
- <p>年龄: <input type="text" name="age"></p>
- <p>生日: <input type="text" name="bir"></p>
- <p><input type="submit" value="添加"></p>
- </form>
- </body>
- </html>
复制代码
## 查询记录(Read)
使用类名.objects.all()获取所有记录,返回QuerySet对象,可在模板中迭代:
- def all_person(request):
- person_lst = models.Person.objects.all()
- return render(request, 'app01/all_person.html', {'person_lst': person_lst})
复制代码
模板中遍历显示数据,注意日期字段使用|date:'Y-m-d'过滤器格式化:
- <table border="1">
- <tr><td>序号</td><td>id</td><td>姓名</td><td>年龄</td><td>生日</td><td>操作</td></tr>
- {% for person in person_lst %}
- <tr>
- <td>{{ forloop.counter }}</td>
- <td>{{ person.id }}</td>
- <td>{{ person.name }}</td>
- <td>{{ person.age }}</td>
- <td>{{ person.birthday|date:'Y-m-d' }}</td>
- <td>
- <a href="/app01/edit_person/?id={{ person.id }}">修改</a>
- <a href="/app01/delete_person/?id={{ person.id }}">删除</a>
- </td>
- </tr>
- {% endfor %}
- </table>
复制代码
## 删除记录(Delete)
删除有两种常用方式:get()取出单个对象后调用delete(),或filter()过滤后删除。推荐使用filter(),因为即使没有匹配记录也不会抛出异常:
- def delete_person(request):
- ids = request.GET.get('id')
- # 方式一:get().delete()
- # person_obj = models.Person.objects.get(id=ids)
- # person_obj.delete()
- # 方式二:filter().delete()
- ret = models.Person.objects.filter(id=ids).delete()
- return redirect('/app01/all_person/')
复制代码
## 修改记录(Update)
修改也有两种模式:先查询出对象,修改属性后save();或者直接用filter().update()批量更新。后者更简洁,且会执行一条UPDATE SQL语句:
- def edit_person(request):
- if request.method == 'POST':
- usrname = request.POST.get('username')
- age = request.POST.get('age')
- bir = request.POST.get('bir')
- id = request.POST.get('id')
- # 方式一:对象赋值后save()
- # person_obj = models.Person.objects.get(id=id)
- # person_obj.name = usrname
- # person_obj.age = age
- # person_obj.birthday = bir
- # person_obj.save()
- # 方式二:filter().update()
- models.Person.objects.filter(id=id).update(name=usrname, age=age, birthday=bir)
- return redirect('/app01/all_person/')
- else:
- id = request.GET.get('id')
- person_obj = models.Person.objects.get(id=id)
- return render(request, 'app01/edit_person.html', {'person_obj': person_obj})
复制代码
修改用的模板同样需要包含CSRF令牌,并将现有数据填充到输入框中:
- <!DOCTYPE html>
- <html>
- <head><meta charset="UTF-8"><title>修改用户</title></head>
- <body>
- <form action="/app01/edit_person/" method="post">
- <p><input type="hidden" name="id" value="{{ person_obj.id }}"></p>
- {% csrf_token %}
- <p>用户名: <input type="text" name="username" value="{{ person_obj.name }}"></p>
- <p>年龄: <input type="text" name="age" value="{{ person_obj.age }}"></p>
- <p>生日: <input type="text" name="bir" value="{{ person_obj.birthday|date:'Y-m-d' }}"></p>
- <p><input type="submit" value="保存"></p>
- </form>
- </body>
- </html>
复制代码
## 总结
通过上述代码,我们完整实现了Django ORM的增删改查操作。ORM屏蔽了底层数据库差异,开发者只需关注Python对象的操作,极大地提高了开发效率。在实际项目中,还可以利用ORM的过滤、排序、聚合、事务等高级功能进一步优化数据访问层。对于初学者,掌握Model定义及CRUD是进入Django Web开发的第一步。 |