django前后端不分离学习笔记,记录 ModelForm方法,增删改查

目录

 一、models.py

 二、app.views.py

三、HTML

父类html

信息查询界面

信息增加

 修改信息

删除信息

四、路由文件


天天学习,天天向上 

 一、models.py

# models.py

from django.db import models

class PrettyNum(models.Model):
    """靓号管理"""
    mobile = models.CharField(verbose_name='手机号码', max_length=11)
    price = models.DecimalField(verbose_name='价格', default=0, decimal_places=2, max_digits=10)

    level_choices = (
        (1, '1级'),
        (2, '2级'),
        (3, '3级'),
        (4, '4级'),
        (5, '5级'),
    )
    level = models.SmallIntegerField(choices=level_choices, verbose_name='级别', default=1)
    status_choices = (
        (1, '已占用'),
        (2, '未占用'),
    )
    status = models.SmallIntegerField(choices=status_choices , verbose_name='状态', default=2)

 二、app.views.py

# app.views.py

from django import forms
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from mobile_app import models

from mobile_app import models


class PrettyModelForm(forms.ModelForm):
    """定义models.PrettyNum 的ModelForm组件"""
    # 重定义mobile 字段的模型,检验手机号码格式,为下面增加手机号码时候做准备,报错会返回前端页面提示
    mobile = forms.CharField(label='手机号码', validators=[RegexValidator(r'^1[3-9]\d{9}', "手机号码格式错误")])

    class Meta:
        model = models.PrettyNum
        # 表示 读取全部字段
        fields = "__all__"

        # fields = ['mobile','price','level','status']  #  单独读取某些要用的字段
        # exclude = ['status']  # 除了status字段,其他都要

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  # 父类继承 __init__
        for name, field in self.fields.items():  # 把models的 字段名和verbose_name 一起打包
            field.widget.attrs = {'class': 'form-control', 'placeholder': field.label}


def mobile_info(request):
    # -level  == desc  select * from 表名 order by 字段 desc
    if request.method == 'GET':
        data_list = models.PrettyNum.objects.all().order_by('-level')
        return render(request, 'mobile_list.html', {'data_list': data_list})


def mobile_add(request):
    if request.method == 'GET':
        form = PrettyModelForm()
        return render(request, 'mobile_add.html', {'form': form})

    form = PrettyModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        return redirect('/mobile/info/')

    # 校验失败,返回前端报错信息
    return render(request, 'mobile_add.html', {'form': form})


def mobile_update(request, nid):
    row_objects = models.PrettyNum.objects.get(id=nid)
    if request.method == 'GET':
        form = PrettyModelForm(instance=row_objects)
        return render(request, 'mobile_update.html', {'form': form})

    form = PrettyModelForm(data=request.POST, instance=row_objects)
    if form.is_valid():
        form.save()
        return redirect('/mobile/info/')

    return render(request, 'mobile_update.html', {'form': form})


def mobile_del(request, nid):
    models.PrettyNum.objects.get(id=nid).delete()
    return redirect('/mobile/info/')


 对代码写法有疑问的,可以参考以下代码代码写法不一样的,实际是一样的效果:

# 方法一:
def mobile_update(request, nid):
    row_objects = models.PrettyNum.objects.get(id=nid)
    if request.method == 'GET':
        form = PrettyModelForm(instance=row_objects)
        return render(request, 'mobile_update.html', {'form': form})

    form = PrettyModelForm(data=request.POST, instance=row_objects)
    if form.is_valid():
        form.save()
        return redirect('/mobile/info/')

    return render(request, 'mobile_update.html', {'form': form})



# 方法二:
def mobile_update2(request, nid):
    row_objects = models.PrettyNum.objects.get(id=nid)
    if request.method == 'GET':
        """instance=row_objects表示从a标签跳转过来的时候,在input框里显示原来要修改的信息"""
        form = PrettyModelForm(instance=row_objects)
        return render(request, 'mobile_update.html', {'form': form})

    if request.method == 'POST':
        """instance=row_objects表示修改参数的时候,是对这个id列参数进行修改,如果没有这个参数,会变成新增信息,达不到想要的效果"""
        form = PrettyModelForm(data=request.POST, instance=row_objects)  
        if form.is_valid(): # 校验前端输入信息是否为空
            form.save()      # 提交到数据库保存
            return redirect('/mobile/info/')  # 添加成功之后,重定向返回信息列表
        else:
            # 检验失败,返回当前页面,提示错误信息,不能为空
            return render(request, 'mobile_update.html', {'form': form}) 
        

三、HTML

父类html

1、插件bootstrap-4.6.2、fontawesome-free-5.15.4

# index.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static '/plugins/bootstrap-4.6.2-dist/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static '/plugins/fontawesome-free-5.15.4-web/css/all.min.css' %}">

</head>
<body>
<div>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="/user/info/">信息管理系统</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item active">
                    <a class="nav-link" href="/depart/list/">部门管理 <span class="sr-only">(current)</span></a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="/user/info/">用户列表</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="/mobile/info/">靓号管理</a>
                </li>
            </ul>
            <div class="form-inline my-2 my-lg-0">
                <ul class="navbar-nav mr-auto">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">登 陆<span class="sr-only">(current)</span></a>
                    </li>
                </ul>
                <div class="dropdown">
                    <a class="btn btn-secondary dropdown-toggle" href="#" role="button" data-toggle="dropdown"
                       aria-expanded="false">
                        当前用户
                    </a>
                    <div class="dropdown-menu">
                        <a class="dropdown-item" href="#">个人信息</a>
                        <a class="dropdown-item" href="#">修改密码</a>
                        <a class="dropdown-item" href="#">注销</a>
                    </div>
                </div>
            </div>
        </div>
    </nav>
</div>

<div>
    {% block content %}{% endblock %}
</div>


<script src="{% static '/js/jquery-3.7.1.min.js' %}."></script>
<script src="{% static '/plugins/bootstrap-4.6.2-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static '/plugins/fontawesome-free-5.15.4-web/js/all.min.js' %}"></script>
</body>
</html>

信息查询界面

1、copy我的代码时候,注意我的模板是用的继承的父类

2、<a href="/mobile/{{ data.id }}/update/">编辑</a>
   

a标签跳转的时候,携带了ID在get请求上面,后端获取了ID就知道 修改/删除 那一条数据

3、get_字段名_display(),在django是一个方法,专门的是为了获取model.py中status_choices和level_choices中的“文字”在前端显示,因为数据记录的是数字不是文字

注意:在前端写法不用写“()”括号,浏览器会自动帮你处理,在后端使用的时候就要括号

{% extends 'index.html' %}
{% block content %}
    <div class="container">
        <div style="width: 100%;margin: 10px">
            <a href="/mobile/add/">
               <i class="fa fa-plus-circle" aria-hidden="true"></i>
                添加手机号码信息
            </a>

        </div>
        <table class="table">
            <thead class="thead-dark">
            <tr>
                <th scope="col">ID</th>
                <th scope="col">手机号码</th>
                <th scope="col">价格</th>
                <th scope="col">等级</th>
                <th scope="col">状态</th>
                <th scope="col">操作</th>

            </tr>
            </thead>
            <tbody>
            {% for data in data_list %}
                <tr>
                    <th scope="row">{{ data.id }}</th>
                    <td>{{ data.mobile }}</td>
                    <td>{{ data.price }}</td>
                    <td>{{ data.get_level_display }}</td>
                    <td>{{ data.get_status_display }}</td>
                    <td>
                        <a href="/mobile/{{ data.id }}/update/">编辑</a>
                        <a href="/mobile/{{ data.id }}/delete/">删除</a>
                    </td>
                </tr>
            {% endfor %}

            </tbody>
        </table>
    </div>

{% endblock %}

信息增加

1、novalidate表示取消前端的检验,因为不同的浏览器检验的方法不同,不一定准确,用自己的后端检验

2、foo.errors.0 

foo.eroers是一个列表,错误信息可能有很多,0获取列表第一个错误信息

{% extends 'index.html' %}

{% block content %}
    <div class="container">
        <a href="/mobile/add/">
            <button type="button" class="btn btn-primary" style="margin-bottom: 10px">
                <i class="fa fa-plus-circle" aria-hidden="true"></i>
                添加号码信息
            </button>
        </a>
           
        <--novalidate表示取消前端的检验,因为不同的浏览器检验的方法不同,不一定准确,我用自己的后端检验-->
        <form  method="post" novalidate>
            {% csrf_token %}

            {% for foo in form %}
                <div>{{ foo.label }}</div>
                <div>
                    {{ foo }}
                    {{ foo.errors.0}}
                </div>
            {% endfor %}
            <div>
                <input type="submit" value="提交">
            </div>

        </form>
    </div>

{% endblock %}

 修改信息

{% extends 'index.html' %}

{% block content %}
    <div class="container">
        <a href="/mobile/update/">
            <button type="button" class="btn btn-primary" style="margin-bottom: 10px">
                <i class="fa fa-plus-circle" aria-hidden="true"></i>
                修改号码信息
            </button>
        </a>

        <form  method="post" novalidate>
            {% csrf_token %}

            {% for foo in form %}
                <div>{{ foo.label }}</div>
                <div>
                    {{ foo }}
                    {{ foo.errors.0}}
                </div>
            {% endfor %}
            <div>
                <input type="submit" value="提交">
            </div>

        </form>
    </div>

{% endblock %}

删除信息

 1、   <a href="/mobile/{{ data.id }}/delete/">删除</a>

a标签携带过去的id,后端根据id直接删除就行了,不需要跳转其他界面,重定向当前页面

四、路由文件

1、主路由文件

from django.contrib import admin
from django.urls import path,include
from staff_app import views


urlpatterns = [
    path('admin/', admin.site.urls),
    path('mobile/', include('mobile_app.urls')),

]

2、分路由文件

<int:nid>可以理解为正则匹配,主要为了a标签跳转的时候,携带nid给后端

from django.urls import path

from mobile_app import views

urlpatterns = [
    path('info/',views.mobile_info),
    path('add/', views.mobile_add),
    path('<int:nid>/update/', views.mobile_update),
    path('<int:nid>/delete/', views.mobile_del),

]

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,我可以提供一个简单的示例代码,以便您了解如何使用Django进行前后分离删改操作。请注意,以下代码仅供参考,您需要根据自己的需求进行修改和完善。 首先,我们需要创建一个Django项目,并在其中创建一个应用程序。在应用程序中,我们需要定义模型以及处理HTTP请求的视图函数。 下面是一个简单的模型示例: ```python # models.py from django.db import models class Product(models.Model): name = models.CharField(max_length=100) description = models.TextField() price = models.DecimalField(max_digits=10, decimal_places=2) ``` 然后,我们需要创建视图函数来处理HTTP请求。在这个示例中,我们将创建一个基于类的视图,并使用Django Rest Framework提供的GenericAPIView和ModelMixin来实现CRUD操作。 ```python # views.py from rest_framework import generics, mixins from .models import Product from .serializers import ProductSerializer class ProductListCreateAPIView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Product.objects.all() serializer_class = ProductSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) class ProductRetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Product.objects.all() serializer_class = ProductSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) ``` 上述视图函数中,我们定义了两个基于类的视图:ProductListCreateAPIView和ProductRetrieveUpdateDestroyAPIView。ProductListCreateAPIView用于创建和列出产品,ProductRetrieveUpdateDestroyAPIView用于获取、更新和删除一个特定的产品。 接下来,我们需要定义序列化器来将模型转换为JSON格式。在这个示例中,我们使用Django Rest Framework提供的ModelSerializer。 ```python # serializers.py from rest_framework import serializers from .models import Product class ProductSerializer(serializers.ModelSerializer): class Meta: model = Product fields = '__all__' ``` 最后,我们需要在urls.py中定义路由,以便将HTTP请求路由到正确的视图函数。 ```python # urls.py from django.urls import path from .views import ProductListCreateAPIView, ProductRetrieveUpdateDestroyAPIView urlpatterns = [ path('products/', ProductListCreateAPIView.as_view(), name='product_list_create'), path('products/<int:pk>/', ProductRetrieveUpdateDestroyAPIView.as_view(), name='product_retrieve_update_destroy'), ] ``` 现在,我们已经完成了一个简单的Django前后分离删改示例。您可以使用前框架(如React或Vue.js)来处理HTTP请求并呈现数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

散文诗`

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值