基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)

项目实战

    • 项目开发流程
    • 项目准备工作
    • 项目部门管理
      • UI设计
      • depart_list
      • 模板继承
      • depart_add
      • depart_delete
      • depart_edit
    • 项目用户管理
      • user_list
      • user_add
      • Form和ModelForm
        • Form
        • ModelForm
      • user_add(ModelForm)
      • user_edit
      • user_delete

号外号外,基于Pycharm的Django学习,项目实战来啦!

项目开发流程

实战之前,我们先来结合前面学习的知识,捋一捋整个项目开发的流程:

  1. 新建项目
  2. 创建app并注册
  3. 设计表结构
  4. 在MYSQL生成表
  5. 静态文件管理
  6. 代码编写
  7. 测试

项目准备工作

上述1-5,其实我们在之前就已经接触过了,所以在这个项目实战中,就当作是准备工作,大家先提前完成,有不懂的也可以看我之前写的博客。

第一步:新建项目

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第1张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第2张图片

第二步:创建app并注册

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第3张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第4张图片

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第5张图片

第三步:设计表结构

from django.db import models

# Create your models here.


class Department(models.Model):
    """部门表"""
    # verbose_name注解 相当于给我们程序员自己看代码时的字段含义提示
    title = models.CharField(verbose_name="部门", max_length=32)


class UserInfo(models.Model):
    """员工表"""
    name = models.CharField(verbose_name="姓名", max_length=16)
    password = models.CharField(verbose_name="密码", max_length=64)
    age = models.IntegerField(verbose_name="年龄")
    # max_digits表示最大位数 decimal_places表示小数位数 default表示默认值
    account = models.DecimalField(verbose_name="账户", max_digits=10, decimal_places=2, default=0)
    create_time = models.DateTimeField(verbose_name="入职时间")

    # 存入外键 表示员工所属部门ID 节省存储字节数 需要加入约束 即只能是部门表中已经存在的id 并且需要设置当部门表被删除 其为级联删除或者可以置空
    # 存入名称 表示员工所属部门名称 主要用于优化检索速度

    # to表示和哪张表连接  to_field表示和哪个字段连接 on_delete表示部门表删除时员工表做出的操作
    depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)

    # Django约束 由于性别只有男和女 所以可以通过choices选择哪一些
    gender_choices = (
        (1, "男"),
        (2, "女")
    )
    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

第四步:在MYSQL生成表

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    # 数据库名字
    'NAME':'写自己的名字',
    # 用户名
    'USER': 'root',
    # 密码
    'PASSWORD': '写自己的密码',
    # 主机
    'HOST': 'localhost',
    # 端口
    'PORT': '3306',
    }
}

python manage.py makemigrations
python manage.py migrate

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第6张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第7张图片

第五步:静态文件管理

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第8张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第9张图片

项目部门管理

UI设计

先看一下页面大致UI设计:

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第10张图片

depart_list

于是开始编写页面:

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第11张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第12张图片

页面整体布局采用的是bootstrap框架,上面的是一个导航条,下面的是一个面板加表格的结构,先使用的静态数据进行测试页面。

大部分需要实现跳转的,哪怕长得再像按钮,其实都是一个a标签,然后设置class为btn属性。

{% load static %}




    
    
    
    Title
    
    
    



部门列表
ID 名称 操作
1 销售部 编辑 删除
2 技术部 编辑 删除
3 广告部 编辑 删除

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第13张图片
下面将静态数据换成从数据库进行获取的数据。

{% load static %}




    
    
    
    Title
    
    
    



部门列表
{% for data in data_list %} {% endfor %}
ID 名称 操作
{{data.id}} {{data.title}} 编辑 删除

效果和上述一样,只不过这里的数据是从数据库来的,更加符合开发。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第14张图片

模板继承

我们在访问一个网站,比如淘宝、京东时,我们会发现,其实每次实现页面跳转的时候,它的每一个页面的导航条都是相同的,那如果每一个页面都写同样的内容,你会不会觉得很繁琐啊,那么怎么办呢?

模板继承!

导航条:layout.html

{% load static %}




    
    
    
    Title
    
    
    



{% block content %}{% endblock %}

添加页面:depart_add.html

{% extends 'layout.html' %}

{% block content %}

{% endblock %}

这样就可以了,当然,如果对其有多处改动,那也可以多加几个下面部分:

{% block 名称 %}

{% endblock %}

测试结果如下:

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第15张图片

depart_add

模板继承测试成功后,下面开始正式编写depart_add页面的编写了。

添加页面的主体是面板加表单设计。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第16张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第17张图片

{% extends 'layout.html' %}

{% block content %}

新建部门

{% csrf_token %}
{% endblock %}

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第18张图片
基础样式出来了后,我们就需要继续实现页面跳转。

def depart_add(request):
    # 如果是get请求
    if request.method == "GET":
        return render(request, "depart_add.html")
    # 如果是post请求 获取用户提交的数据
    title = request.POST.get("title")
    # 将数据加入到数据库 (此处默认数据都是合法的 后面用Form和ModelForm实现)
    models.Department.objects.create(title=title)
    # 重定向到用户列表
    return redirect("/depart/list/")

有没有发现把我们前面学习的东西都用起来了?
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第19张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第20张图片

depart_delete

是不是很有成就感呢?下面来写一个删除吧,和上一篇案例中的删除大同小异奥!

首先要在depart_list中找到删除对应的位置,然后实现url跳转。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第21张图片

def depart_delete(request):
    # 获取需要删除的id
    nid = request.GET.get("nid")
    # 在数据库删除对应内容
    models.Department.objects.filter(id=nid).delete()
    # 重新返回列表展示页面
    return redirect("/depart/list/")

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第22张图片

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第23张图片

此处相当于更改为跳转到url为/depart/delete的位置,并且将用户id传递过来,在urls.py文件中的url - 视图函数对应中,可以知道其对应会执行depart_delete函数,于是获取参数、删除内容后,重定向到展示页面,整个流程一气呵成。

depart_edit

编辑页面,我们想想它长什么样子,其和我们新建部门页面应该差不多,但是差别在于,编辑的时候,你点进去的时候,部门的默认值是原来需要编辑的内容。

有了id有了一切,传id。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第24张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第25张图片

def depart_edit(request, nid):
    # 根据nid获取数据
    edit_data = models.Department.objects.filter(id=nid).first()
    return render(request, "depart_edit.html", {"edit_data": edit_data})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第26张图片

{% extends 'layout.html' %}

{% block content %}

新建部门

{% csrf_token %}
{% endblock %}

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第27张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第28张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第29张图片
再来完善一下页面跳转。

def depart_edit(request, nid):
    # 如果是get请求
    if request.method == "GET":
        # 根据nid获取数据
        edit_data = models.Department.objects.filter(id=nid).first()
        return render(request, "depart_edit.html", {"edit_data": edit_data})
    
    # 获取用户更新的title
    title = request.POST.get("title")
    # 对数据库中进行修改
    models.Department.objects.filter(id=nid).update(title=title)
    
    # 重定向为部门列表
    return redirect("/depart/list/")

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第30张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第31张图片
一直没看数据库,这里一起看一下吧~

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第32张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第33张图片

记得刷新!空白部分,右键刷新!

项目用户管理

部门管理差不多了,下面来看用户管理吧!

用户管理可不一般,也就是字段多了点,那么在获取内容的时候也有很多小细节需要注意奥!

user_list

首先我们需要为数据库准备一些数据:

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第34张图片

def user_orm(request):
    # 虽然在models.py中其为depart,但是实际上是depart_id,在操作的时候注意
    models.UserInfo.objects.create(name="王晓曼", password="123520", age=20, account=99999, create_time="2022-09-01",
                                   depart_id=1, gender=2)
    models.UserInfo.objects.create(name="王尚春", password="666666", age=49, account=199999, create_time="2000-01-01",
                                   depart_id=2, gender=1)
    models.UserInfo.objects.create(name="彭艳", password="111111", age=48, account=299999, create_time="2001-01-01",
                                   depart_id=3, gender=2)
    models.UserInfo.objects.create(name="王梦迪", password="131420", age=28, account=399999, create_time="2015-06-14",
                                   depart_id=6, gender=2)
    models.UserInfo.objects.create(name="黄伟", password="888888", age=33, account=499999, create_time="2012-12-31",
                                   depart_id=7, gender=1)
    return HttpResponse("成功")

然后在导航条里加上用户管理这一个标签。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第35张图片
用户列表,其实和部门列表差不多,只是字段可能不一样,先仿着部门列表写。

{% extends 'layout.html' %}

{% block content %}



用户列表
{% for data in data_list %} {% endfor %}
ID 姓名 密码 年龄 余额 入职时间 部门 性别 操作
{{data.id}} {{data.name}} {{data.password}} {{data.age}} {{data.account}} {{data.create_time}} {{data.depart}} {{data.gender}} 编辑 删除
{% endblock %}

测试效果如下:

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第36张图片

但是这样的效果肯定不好,所以我们需要在后端调整。

def user_list(request):
    data_list = models.UserInfo.objects.all()
    # 由于数据比较复杂 所以需要在后端进行调试数据格式 当然有可能前后端数据格式调整代码会不同 也会有局部更改
    for data in data_list:
        print(data.create_time.strftime("%Y-%m-%d"))
    return render(request, "user_list.html", {"data_list": data_list})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第37张图片
但是我们发现性别不是我们想要的展示数据,于是我们想起在定义表的时候,有一个gender_choices这个变量,那么怎么将数据展示成我们想要的呢?

def user_list(request):
    data_list = models.UserInfo.objects.all()
    # 由于数据比较复杂 所以需要在后端进行调试数据格式 当然有可能前后端数据格式调整代码会不同 也会有局部更改
    for data in data_list:
        # strftime("%Y-%m-%d")是后端将datetime类型转换为字符串形式
        print(data.create_time.strftime("%Y-%m-%d"))
        # 将元组套元组的类型 转换成 对应的字段
        print(data.get_gender_display())
    return render(request, "user_list.html", {"data_list": data_list})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第38张图片

那么depart_id怎么展示成对应的部门名称呢?

def user_list(request):
    data_list = models.UserInfo.objects.all()
    # 由于数据比较复杂 所以需要在后端进行调试数据格式 当然有可能前后端数据格式调整代码会不同 也会有局部更改
    for data in data_list:
        # strftime("%Y-%m-%d")是后端将datetime类型转换为字符串形式
        print(data.create_time.strftime("%Y-%m-%d"))
        # 将元组套元组的类型 转换成 对应的字段
        print(data.get_gender_display())
        # 拿取部门id对应的部门名称 我们知道在定义表的时候 定义的是depart 但是数据库给我们存的是depart_id 那么depart其实对应的是表的那一行的对象
        print(data.depart.title)
    return render(request, "user_list.html", {"data_list": data_list})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第39张图片
在后端测试好了后,移植到前端了。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第40张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第41张图片
是不是感觉很好呢?

user_add

其实添加用户和新建部门是一样的原理,但是可能字段会更多一点。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第42张图片

{% extends 'layout.html' %}

{% block content %}

新建用户

{% csrf_token %}
{% endblock %}
def user_add(request):
    # 拿到性别元组 和 部门信息
    gender_choices = models.UserInfo.gender_choices
    depart_list = models.Department.objects.all()
    # 如果是get请求
    if request.method == "GET":
        return render(request, "user_add.html", {"gender_choices": gender_choices, "depart_list": depart_list})
    # 如果是post请求 获取用户提交的数据
    name = request.POST.get("name")
    password = request.POST.get("password")
    age = request.POST.get("age")
    account = request.POST.get("account")
    create_time = request.POST.get("create_time")
    depart = request.POST.get("depart")
    gender = request.POST.get("gender")
    # 将数据加入到数据库 (此处默认数据都是合法的 后面用Form和ModelForm实现)
    models.UserInfo.objects.create(name=name, password=password, age=age, account=account, create_time=create_time,
                                   depart_id=depart, gender=gender)
    # 重定向到用户列表
    return redirect("/user/list/")

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第43张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第44张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第45张图片

Form和ModelForm

有没有觉得如果字段很多的话,这也太复杂了吧!

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第46张图片

没关系,Django给我们提供了Form和ModelForm奥,一起先来看看他们的基本用法吧!

Form

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第47张图片

ModelForm

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第48张图片
当然也支持自定义字段和Model字段一起!
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第49张图片

user_add(ModelForm)

为了区分,我们首先在用户列表中,新增加一个按钮。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第50张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第51张图片
views.py中增加如下:

from django import forms


class UserModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age"]


def user_model_form_add(request):
    form = UserModelForm()
    return render(request, "user_model_form_add.html", {"form": form})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第52张图片
先测试基本数据(不考虑样式):




    
    Title


{% csrf_token %} {{form.name.label}}:{{form.name}} {{form.password.label}}:{{form.password}} {{form.age.label}}:{{form.age}}

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第53张图片
对form进行循环:




    
    Title


{% csrf_token %} {% for field in form %} {{field.label}}:{{field}} {% endfor %}

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第54张图片
剩下的字段都加上,看一下效果:

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第55张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第56张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第57张图片

有没有发现其他的很方便,但是depart怎么肥四?!

首先我们没有写verbose_name,所以直接把字段名写出来了。

其次这个为对象,所以直接输出了对象。

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第58张图片
搞定!
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第59张图片
现在集成到bootstrap中!

{% extends 'layout.html' %}

{% block content %}

新建ModelForm用户

{% csrf_token %} {% for field in form %}
{{field}}
{% endfor %}
{% endblock %}

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第60张图片
但是长得有点丑啊!

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第61张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第62张图片
把所有的都加上:

from django import forms


class UserModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", "account", "create_time", "depart", "gender"]

        # 插件
        # widgets = {
        #     "name": forms.TextInput(attrs={"class": "form-control"})
        # }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for name, field in self.fields.items():
            field.widget.attrs = {"class": "form-control", "placeholder": field.label}


def user_model_form_add(request):
    form = UserModelForm()
    return render(request, "user_model_form_add.html", {"form": form})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第63张图片
完善POST后的相关处理:

def user_model_form_add(request):
    if request.method == "GET":
        form = UserModelForm()
        return render(request, "user_model_form_add.html", {"form": form})
    # 用Post提交的数据 进行数据校验
    form = UserModelForm(data=request.POST)
    if form.is_valid():
        # 如果数据合法  保存到数据库
        print(form.cleaned_data)
        form.save()
        return redirect("/user/list/")
    else:
        print(form.errors)
        return render(request, "user_model_form_add.html", {"form": form})

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第64张图片
怎么将提示变成中文呢?

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第65张图片

LANGUAGE_CODE = 'zh-hans'

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第66张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第67张图片
如果对于姓名字段,添加一些限制呢?

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第68张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第69张图片
正确的添加:
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第70张图片

总而言之:ModelForm针对操作数据库某个表,其他还是Form。

user_edit

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第71张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第72张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第73张图片

def user_edit(request, nid):
    if request.method == "GET":
        # 根据id去数据库获取编辑的那一行
        row_object = models.UserInfo.objects.filter(id=nid).first()
        form = UserModelForm(instance=row_object)
        return render(request, "user_edit.html", {"form": form})

    # 完成编辑后保存到当前对象中 而不是新增一个用户 (该行可放在最上面)
    row_object = models.UserInfo.objects.filter(id=nid).first()
    # 用Post提交的数据 进行数据校验
    form = UserModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        # 如果数据合法  保存到数据库
        print(form.cleaned_data)
        # 默认保存的是用户输入的所有数据 如果想要再保存用户输入的额外的值
        # form.instance.字段名=值
        form.save()
        return redirect("/user/list/")
    else:
        print(form.errors)
        return render(request, "user_edit.html", {"form": form})

页面就和用户添加的页面差不多,只需要修改标题。

{% extends 'layout.html' %}

{% block content %}

编辑用户

{% csrf_token %} {% for field in form %}
{{field}} {{field.errors.0}}
{% endfor %}
{% endblock %}

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第74张图片

user_delete

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第75张图片
基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)_第76张图片
叮咚,完成!

你可能感兴趣的:(Python,django,pycharm,学习)