python-web开发[19]之Django开发

本文回顾了Django项目的安装与配置,介绍了创建app、设置静态文件和模板路径,数据库连接与模型设计,以及如何通过ModelForm进行表单操作。重点讲解了文件上传、数据库CRUD、Ajax应用和图表库的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

day19 Django开发

知识点的回顾:

  • 安装Django
pip install django
  • 创建Django项目
>>> django-admin startproject mysite

注意:Pycharm可以创建。如果用Pycharm创建,记得settings.py中的DIR templates 删除。

  • 创建app & 注册
>>>python manage.py startapp app01
>>>python manage.py startapp app02
>>>python manage.py startapp app03
INSTALLED_APPS = [
    ……
    'app01.apps.App01Config'
]

注意:否则app下的models.py写类时,无法在数据库中创建表。

  • 配置 静态文件路径 & 模板的路径(放在app目录下)。
  • 配置数据库相关操作(MySQL)
    • 第三方模块(django3版本)
pip install mysqlclient
  • 自己先去MySQL创建一个数据库。
  • 配置数据库连接settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'gx_day16',  # 数据库名字
        'USER': 'root',
        'PASSWORD': 'root123',
        'HOST': '127.0.0.1',  # 那台机器安装了MySQL
        'PORT': 3306,
    }
}
  • 在app下的models.py中编写
from django.db import models


class Admin(models.Model):
    """ 管理员 """
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)

    def __str__(self):
        return self.username

    
class Department(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name='标题', max_length=32)

    def __str__(self):
        return self.title
  • 执行两个命令:将models.py中的表在数据库中进行创建
>>>python manange.py makemigrations
>>>python manange.py migrate
  • 在 urls.py ,路由 ( URL 和 函数的对应关系)。
  • 在views.py,视图函数,编写业务逻辑。
  • templates目录,编写HTML模板(含有模板语法、继承、{% static 'xx'%}
  • ModelForm & Form组件,在我们开发增删改查功能。
    • 生成HTML标签(生成默认值)
    • 请求数据进行校验。 - clean_data, 手机号,非空等
    • 保存到数据库(ModelForm)
    • 获取错误信息。
  • Cookie和Session,用户登录信息保存起来。
  • 中间件,基于中间件实现用户认证 ,基于:process_request。 – 页面都需要先登录的认证校验
  • ORM操作
models.User.objects.filter(id="xxx")
models.User.objects.filter(id="xxx").order_by("-id")
  • 分页组件。

1.Ajax请求

2.订单

在这里插入图片描述

class Order(models.Model):
    """ 订单 """
    oid = models.CharField(verbose_name="订单号", max_length=64)
    title = models.CharField(verbose_name="名称", max_length=32)
    price = models.IntegerField(verbose_name="价格")

    status_choices = (
        (1, "待支付"),
        (2, "已支付"),
    )
    status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=1)
    admin = models.ForeignKey(verbose_name="管理员", to="Admin", on_delete=models.CASCADE)

想要去数据库中获取数据时:对象/字典

# 对象,当前行的所有数据。
row_object = models.Order.objects.filter(id=uid).first()
row_object.id
row_object.title
# 字典,{"id":1,"title":"xx"}
row_dict = models.Order.objects.filter(id=uid).values("id","title").first()  # 从数据库中获取数据,1-对象;2-字段(values)
# queryset = [obj,obj,obj,]
queryset = models.Order.objects.all()  # 对象
# queryset = [ {'id':1,'title':"xx"},{'id':2,'title':"xx"}, ]
queryset = models.Order.objects.all().values("id","title")  # values: 字段对象
# queryset = [ (1,"xx"),(2,"xxx"), ]
queryset = models.Order.objects.all().values_list("id","title") # values_list直接元素的元组

三种方式: 对象、字典、元组

小结

至此,基于Ajax + 对话框的形式实现的页面的增删改查。

  • 表单,实现增删改查。
  • Ajax,实现增删改查。

3.图表

  • highchart,国外工具。
  • echarts,国内百度开源工具。

更多参考文档:https://echarts.apache.org/handbook/zh/get-started
echarts模块
在这里插入图片描述

highchart模块
在这里插入图片描述

4.文件基本操作

4.1 基本操作
<form method="post" enctype="multipart/form-data">
  <!-- enctype="multipart/form-data" 实现上传真正的图片,如果不添加的话,就只上传的文件名-->
  {% csrf_token %}
  <input type="text" name="username">
  <input type="file" name="avatar">
  <input type="submit" value="提交">
</form>
from django.shortcuts import render, HttpResponse

def upload_list(request):
    if request.method == "GET":
        return render(request, 'upload_list.html')

    # # 'username': ['big666']
    # print(request.POST)  # 请求体中数据

    # # {'avatar': [<InMemoryUploadedFile: 图片 1.png (image/png)>]}> 这是一个文件对象
    # print(request.FILES)  # 请求发过来的文件 {}

    file_object = request.FILES.get("avatar")
    # print(file_object.name)  # 上传的文件名:WX20211117-222041@2x.png,文件是一个对象

    f = open(file_object.name, mode='wb')
    for chunk in file_object.chunks(): # 数据是一块一块的
        f.write(chunk)
    f.close()

    return HttpResponse("...")

4.2 案例:批量上传数据

目标: 在部门管理模块,增加一个面板,支持用户上传文件,并进行下游消费使用。
在这里插入图片描述

def depart_multi(request):
    """ 批量删除(Excel文件)"""
    from openpyxl import load_workbook

    # 1.获取用户上传的文件对象
    file_object = request.FILES.get("exc")

    # 2.对象传递给openpyxl,由openpyxl读取文件的内容
    wb = load_workbook(file_object)
    sheet = wb.worksheets[0]

    # 3.循环获取每一行数据
    for row in sheet.iter_rows(min_row=2):
        text = row[0].value
        exists = models.Department.objects.filter(title=text).exists()
        if not exists:
            models.Department.objects.create(title=text)

    return redirect('/depart/list/')
{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
                批量上传
            </div>
            <div class="panel-body">
                <form method="post" enctype="multipart/form-data" action="/depart/multi/">
                    {% csrf_token %}
                    <div class="form-group">
                        <input type="file" name="exc">
                    </div>
                    <input type="submit" value="上传" class="btn btn-info btn-sm">
                </form>
            </div>
        </div>
        <div style="margin-bottom: 10px">
            <a class="btn btn-success" href="/depart/add/">
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
                新建部门
            </a>
        </div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
                部门列表
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>名称</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {% for obj in queryset %}
                    <tr>
                        <th>{{ obj.id }}</th>
                        <td>{{ obj.title }}</td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/depart/{{ obj.id }}/edit/">编辑</a>
                            <a class="btn btn-danger btn-xs" href="/depart/delete/?nid={{ obj.id }}">删除</a>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{% endblock %}

4.3 案例:混合数据

提交页面时: 用户输入数据+文件(输入不能为空,报错)

  • form生成html标签: type = file
  • 表单的验证
  • form.cleaned_data 获取数据 + 文件对象
import os
from django.conf import settings
from django.shortcuts import render, HttpResponse
from app01 import models


def upload_list(request):
    if request.method == "GET":
        return render(request, 'upload_list.html')

    # # 'username': ['big666']
    # print(request.POST)  # 请求体中数据

    # # {'avatar': [<InMemoryUploadedFile: 图片 1.png (image/png)>]}> 这是一个文件对象
    # print(request.FILES)  # 请求发过来的文件 {}

    file_object = request.FILES.get("avatar")
    # print(file_object.name)  # 上传的文件名:WX20211117-222041@2x.png,文件是一个对象

    f = open(file_object.name, mode='wb')
    for chunk in file_object.chunks(): # 数据是
        f.write(chunk)
    f.close()

    return HttpResponse("...")


from django import forms
from app01.utils.bootstrap import BootStrapForm, BootStrapModelForm


class UpForm(BootStrapForm):
    bootstrap_exclude_fields = ['img']

    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


def upload_form(request):
    title = "Form上传"
    if request.method == "GET":
        form = UpForm()
        return render(request, 'upload_form.html', {"form": form, "title": title})

    form = UpForm(data=request.POST, files=request.FILES)
    if form.is_valid():
        # {'name': '武沛齐', 'age': 123, 'img': <InMemoryUploadedFile: 图片 1.png (image/png)>}
        # 1.读取图片内容,写入到文件夹中并获取文件的路径。
        image_object = form.cleaned_data.get("img")

        # media_path = os.path.join(settings.MEDIA_ROOT, image_object.name)
        media_path = os.path.join("media", image_object.name)
        f = open(media_path, mode='wb')
        for chunk in image_object.chunks():
            f.write(chunk)
        f.close()

        # 2.将图片文件路径写入到数据库
        models.Boss.objects.create(
            name=form.cleaned_data['name'],
            age=form.cleaned_data['age'],
            img=media_path,
        )
        return HttpResponse("...")
    return render(request, 'upload_form.html', {"form": form, "title": title})


from django import forms
from app01.utils.bootstrap import BootStrapModelForm


class UpModelForm(BootStrapModelForm):
    bootstrap_exclude_fields = ['img']

    class Meta:
        model = models.City
        fields = "__all__"


def upload_modal_form(request):
    """ 上传文件和数据(modelForm)"""
    title = "ModelForm上传文件"
    if request.method == "GET":
        form = UpModelForm()
        return render(request, 'upload_form.html', {"form": form, 'title': title})

    form = UpModelForm(data=request.POST, files=request.FILES)
    if form.is_valid():
        # 对于文件:自动保存;
        # 字段 + 上传路径写入到数据库
        form.save()

        return HttpResponse("成功")
    return render(request, 'upload_form.html', {"form": form, 'title': title})
{% extends 'layout.html' %}


{% block content %}

    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title"> {{ title }} </h3>
            </div>
            <div class="panel-body">
                <form method="post" enctype="multipart/form-data" novalidate >
                    {% csrf_token %}

                    {% for field in form %}
                        <div class="form-group">
                            <label>{{ field.label }}</label>
                            {{ field }}
                            <span style="color: red;">{{ field.errors.0 }}</span>
                        </div>
                    {% endfor %}

                    <button type="submit" class="btn btn-primary">提 交</button>
                </form>
            </div>
        </div>
    </div>

{% endblock %}

注意: 就目前而言,目前的静态文件都只能放在static目录下;类似用户上传的这种动态文件放在media目录下。

在django开发过程中,有两个特殊的文件夹:

  • static: 存放静态文件的路径,包括: css/js/项目图片
  • media: 用户上传数据的目录
4.4 启用media
  • 第一步: 在urls.py中进行配置
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings

    re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),

  • 第二步: 在settings.py中进行配置
import os

MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
  • 第三步: 直接在浏览器上进行访问
    在这里插入图片描述

    修改之后的py代码
import os
from django.conf import settings
from django.shortcuts import render, HttpResponse
from app01 import models


def upload_list(request):
    if request.method == "GET":
        return render(request, 'upload_list.html')

    # # 'username': ['big666']
    # print(request.POST)  # 请求体中数据

    # # {'avatar': [<InMemoryUploadedFile: 图片 1.png (image/png)>]}> 这是一个文件对象
    # print(request.FILES)  # 请求发过来的文件 {}

    file_object = request.FILES.get("avatar")
    # print(file_object.name)  # 上传的文件名:WX20211117-222041@2x.png,文件是一个对象

    f = open(file_object.name, mode='wb')
    for chunk in file_object.chunks(): # 数据是
        f.write(chunk)
    f.close()

    return HttpResponse("...")


from django import forms
from app01.utils.bootstrap import BootStrapForm, BootStrapModelForm


class UpForm(BootStrapForm):
    bootstrap_exclude_fields = ['img']

    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


def upload_form(request):
    title = "Form上传"
    if request.method == "GET":
        form = UpForm()
        return render(request, 'upload_form.html', {"form": form, "title": title})

    form = UpForm(data=request.POST, files=request.FILES)
    if form.is_valid():
        # {'name': '武沛齐', 'age': 123, 'img': <InMemoryUploadedFile: 图片 1.png (image/png)>}
        # 1.读取图片内容,写入到文件夹中并获取文件的路径。
        image_object = form.cleaned_data.get("img")

        # media_path = os.path.join(settings.MEDIA_ROOT, image_object.name) # 绝对路径
        media_path = os.path.join("media", image_object.name)  # 相对路径
        f = open(media_path, mode='wb')
        for chunk in image_object.chunks():
            f.write(chunk)
        f.close()

        # 2.将图片文件路径写入到数据库
        models.Boss.objects.create(
            name=form.cleaned_data['name'],
            age=form.cleaned_data['age'],
            img=media_path,
        )
        return HttpResponse("...")
    return render(request, 'upload_form.html', {"form": form, "title": title})

4.5 用modalform实现混合数据新增
  • models.py中新增函数
class City(models.Model):
    """ 城市 """
    name = models.CharField(verbose_name="名称", max_length=32)
    count = models.IntegerField(verbose_name="人口")

    # 本质上数据库也是CharField,自动保存数据。
    img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')
  • 定义modalform
from django import forms
from app01.utils.bootstrap import BootStrapModelForm


class UpModelForm(BootStrapModelForm):
    bootstrap_exclude_fields = ['img']

    class Meta:
        model = models.City
        fields = "__all__"


def upload_modal_form(request):
    """ 上传文件和数据(modelForm)"""
    title = "ModelForm上传文件"
    if request.method == "GET":
        form = UpModelForm()
        return render(request, 'upload_form.html', {"form": form, 'title': title})

    form = UpModelForm(data=request.POST, files=request.FILES)   # 文件上传。
    if form.is_valid():
        # 对于文件:自动保存;
        # 字段 + 上传路径写入到数据库
        form.save()

        return HttpResponse("成功")
    return render(request, 'upload_form.html', {"form": form, 'title': title})

小结

  • 第一种方式:上传文件,自己手动写
  • 第二种方式: form组件,具体文件还是得自己手动写
  • 第三种方式: moelform(表单验证 + 自动保存数据库 + 自动保存文件)

– media文件夹
– models.py文件要素
img = models.FileField(verbose_name=“Logo”, max_length=128, upload_to=‘city/’)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值