侧边栏壁纸
博主头像
进一步,海阔天空 博主等级

进一步,海阔天空

  • 累计撰写 140 篇文章
  • 累计创建 19 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

Django Web开发系列教程【6】- 操作数据库

海阔天空
2023-05-29 / 0 评论 / 0 点赞 / 33 阅读 / 0 字

本节我们将更进一步,实现通过模型对数据库进行数据的创建、读取、更新、删除操作,即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

0

评论区