在Django中,第4章讨论了在视图中执行数据库查询的“愚蠢”方式。传统的做法是在视图函数中直接使用Python库如MySQLdb来执行SQL查询,然后处理查询结果。例如,以下代码片段展示了如何在视图`book_list`中连接MySQL数据库并获取书籍名称:
```python
def book_list(request):
db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost')
cursor = db.cursor()
cursor.execute('SELECT name FROM books ORDER BY name')
names = [row[0] for row in cursor.fetchall()]
db.close()
return render(request, 'book_list.html', {'names': names})
```
这种做法存在几个问题:
1. **硬编码的数据库连接参数**:这些敏感信息(如用户名、密码、数据库名)直接写在代码中,不安全且不易维护。理想的做法是将这些参数存储在Django项目的配置文件或环境变量中。
2. **样板代码过多**:每次都需要手动创建数据库连接、游标、执行查询和关闭连接,这增加了代码的复杂性和重复性。理想情况下,应该通过高层API简化这一过程。
3. **数据库依赖性**:如果想更改数据库引擎(如从MySQL转到PostgreSQL),大量代码需要重写,这不符合DRY(Don't Repeat Yourself)原则。理想情况下,应用程序应使用数据库抽象层来解耦,允许轻松地切换数据库。
4. **可扩展性与社区支持**:对于开源项目,这样的实现方式不利于其他人接手或贡献。如果数据库操作是通用的,应该封装成可复用的功能,以便其他开发者能够轻松地理解和修改。
在更高级的教程或实践中,推荐使用ORM(Object-Relational Mapping,对象关系映射)技术,如Django的内置QuerySet,它能自动处理与数据库的交互,避免硬编码SQL。同时,可以使用Django的Model类来定义数据库结构和查询逻辑,这样既提高了代码的可读性,也减少了与底层数据库的耦合。例如,通过Model类,可以像下面这样查询数据:
```python
from django.db import models
class Book(models.Model):
name = models.CharField()
# 在视图中
books = Book.objects.all().order_by('name')
names = [book.name for book in books]
```
通过这种方式,视图专注于业务逻辑,而底层的数据库操作由Django自动处理,大大提高了代码质量和可维护性。