本节我们将更进一步,实现通过模型对数据库进行数据的创建、读取、更新、删除操作,即CRUD
定义模型
前面的章节中我们已经建立了一个简单的新闻模型,并把模型注册到Django的admin后台管理中,这一节我们将通过Django内置的ORM工具,实现对数据的CRUD操作。首先我们需要定义数据模型,我们定义一个新闻模型,用于保存所有的新闻信息。在models.py中定义News模型,代码如下:
from django.db import models
class News(models.Model):
tgid = models.IntegerField(verbose_name='id号', name='id', primary_key=True, auto_created=True)
title = models.CharField(verbose_name="新闻标题", max_length=1000)
img = models.ImageField(verbose_name="新闻图片路径",upload_to='upload/images')
txt = models.TextField(verbose_name='新闻内容')
dttime = models.DateField(verbose_name='添加时间', auto_now_add=True)
def serialize(self):
print(self)
return {
"id": self.id,
"title": self.title,
"dttime": self.dttime.strftime("%Y-%m-%d"),
"img": self.img.name if self.img else None,
"txt": self.txt
}
执行以下命令,更新数据库:
python manage.py makemigrations
python manage.py migrate
建立表单
新建一个forms.py文件,给News模型建立一个对应的表单。
from .models import News
from django import forms
class NewsForm(forms.ModelForm):
class Meta:
model = News
fields = "__all__"
view函数编写
打开views.py文件,在里面添加如下函数:
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.http import JsonResponse
from django.forms.models import model_to_dict
from .forms import NewsForm
from .models import News
#添加新闻
def add_news(request):
if request.method == "POST":
# 将用户提交数据与NewsForm表单绑定
form = NewsForm(request.POST,request.FILES)
# 表单验证,如果表单有效,将数据存入数据库
if form.is_valid():
form.save()
# 跳转到新闻列表
return redirect(reverse("api433:新闻列表"))
else:
# 否则空表单
form = NewsForm()
return render(request, "news/add_news.html", {"form": form})
# 读取新闻列表
def news_list(request):
# 获得所有数据
list = News.objects.all()
# 指定渲染模板并传递数据
return render(request, "news/news_list.html", {"newsList": list})
# return HttpResponse("newsList")
# 新闻详情
def news_detail(request, pk):
news = get_object_or_404(News, pk=pk)
return render(request, "news/news_detail.html", {"news": news})
#删除新闻
def news_delete(request, pk):
news = News.objects.get(pk=pk)
news.delete()
return redirect(reverse("api433:新闻列表"))
#更新新闻
def news_update(request,pk):
# 从url里获取单个任务的pk值,然后查询数据库获得单个对象实例
news_obj = get_object_or_404(News, pk=pk)
if request.method == 'POST':
form = NewsForm(instance=news_obj, data=request.POST)
if form.is_valid():
form.save()
return redirect(reverse("api433:新闻详情", args=[pk, ]))
else:
form = NewsForm(instance=news_obj)
return render(request, "news/add_news.html", {"form": form, "object": news_obj})
# 获得新闻列表API
def webapi_new_list(request):
# 获得所有数据
list = News.objects.all()
list2 = []
for i in list:
list2.append(i.serialize())
result = {"code": 200, "dataList": list2}
return JsonResponse(result, safe=False)
URL定义
打开urls.py,添加如下的url定义:
from django.urls import path
from . import views
app_name = "api433"
urlpatterns = [
path('', views.index),
path('data_admin/add_news', views.add_news, name='添加新闻'),
path('data_admin/news_list', views.news_list, name="新闻列表"),
path('data_admin/news_detail/<str:pk>', views.news_detail, name="新闻详情"),
path('data_admin/news_delete/<str:pk>', views.news_delete, name="删除新闻"),
path('data_admin/news_update/<str:pk>', views.news_update, name="更新新闻"),
path('webapi/news_list', views.webapi_new_list, name="新闻列表API")
]
建立添加新闻的Template
在templates/news目录,新建一个add_news.html文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加新闻</title>
</head>
<body>
<!--方式一-->
<form action="" method="post" enctype="multipart/form-data">
<!--csrf 全称是 Cross Site Request Forgery。这是 Django 提供的防止伪装提交请求的功能。POST 方法提交的表格,必须有此标签。-->
{% csrf_token %}
{{ form.as_p }}
<div>
<button type="submit">提交</button>
</div>
</form>
<!--方式二-->
<!--<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
<label for="id_id">Id号:</label>
<input type="number" name="id" required id="id_id">
</p>
<p>
<label for="id_title">新闻标题:</label>
<input type="text" name="title" maxlength="1000" required id="id_title">
</p>
<p>
<label for="id_img">新闻图片:</label>
<input type="text" name="img" maxlength="1000" id="id_img">
</p>
<p>
<label for="id_txt">新闻内容:</label>
<textarea name="txt" cols="40" rows="10" required id="id_txt"></textarea>
</p>
<div>
<button type="submit">提交</button>
</div>
</form>-->
</body>
</html>
建立新闻列表的Template
在templates/news目录,新建一个news_list.html文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新闻列表</title>
</head>
<body>
<h3>新闻列表</h3>
{% for item in newsList %}
<div>
{{ item.id }}. {{ item.title }} - {{ items.txt }} <a href="{% url 'api433:新闻详情' item.id %}">新闻详情</a> | <a href="{% url 'api433:删除新闻' item.id %}">删除新闻</a>
</div>
{% endfor %}
<p><a href="/api433/data_admin/add_news"> + 添加新闻</a></p>
</body>
</html>
建立新闻详情的Template
在templates/news目录,新建一个news_detail.html文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新闻详情</title>
</head>
<body>
<p>
<p> 标题: {{ news.title }}
</p>
<p>
内容:{{news.txt}}
</p>
<p>
图片:{{news.imng}}
</p>
<p>
添加时间:{{news.dttime}}
</p>
<p>
<a href="{% url 'api433:更新新闻' news.id %}">更新新闻</a> |
<a href="{% url 'api433:删除新闻' news.id %}">删除新闻</a>
</p>
<p><a href="{% url 'api433:新闻列表' %}">新闻列表</a> |
<a href="{% url 'api433:添加新闻'%}">添加新闻</a>
</p>
</body>
</html>
运行效果
添加新闻
新闻列表
新闻详情
更新新闻
连接MySQL数据库
Django默认使用sqlite数据库,一般生产环境下会使用别的数据库如MySQL或postgres等,这里以MySQL为例介绍如何连接别的数据库。首先需要安装MySQL驱动,通过以下命令安装即可。
pip install pymysql
然后修改项目的setting.py文件,把数据库连接改成如下内容
DATABASES = {
'default': {
# 连接mysql
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbname', #需要提前创建
'USER': 'dbuser',
'PASSWORD': 'dbpassword',
'HOST': '127.0.0.1',
'PORT': '3306'
}
}
接着需要在项目的__init__.py文件中添加如下代码,加载MySQL客户端
import pymysql
pymysql.install_as_MySQLdb()
此时启动项目,如果出现如下错误
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.4.3 or newer is required; you have 1.0.3.
此时我们只需要把__init__.py文件改成如下内容即可
import pymysql
pymysql.version_info = (1, 4, 3, "final", 0)
pymysql.install_as_MySQLdb()
另外还需要安装相应的类库
pip install cryptography
评论区