Python Web开发记录 Day10:Django part4 靓号管理与优化

名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪)
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)

目录

        • 1、数据库准备
        • 2、靓号列表
        • 3、新建靓号
        • 4、编辑靓号
        • 5、删除靓号
        • 6、靓号搜索
        • 7、分页切换
        • 8、优化(整合分类)

在经过前两篇博客的学习,对Django开发管理模块能明显感到愈发熟练,本篇内容将继续增加管理模块,靓号管理,并在此之后对之前的所实现的模块整体进行一个优化,再往后的博客内容将陆续推展到管理员管理、账户登录、以及Ajax等内容。

1、数据库准备

1.首先在models.py中创建用户表,定义数据表及属性字段。

class PrettyNum(models.Model):
    """靓号表"""
    mobile = models.CharField(verbose_name="手机号", max_length=11)
    # 想要允许为空 加上null = True,black = True
    price = models.IntegerField(verbose_name="价格")

    level_choices = (
        (1, "1级"),
        (2, "2级"),
        (3, "3级"),
        (4, "4级"),
    )
    level = models.SmallIntegerField(verbose_name="级别", choices=level_choices, default=1)

    status_choices = (
        (1, "已占用"),
        (2, "未使用")
    )

    status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=2)

2.之后在当前页面终端运行以下数据库转移命令

python manage.py migrate
python manage.py makemigrations

之后运行本地服务器,启动Django项目,Django根据models中定义的内容就会帮咱们自动生成对应的数据表

python manage.py runserver 

在这里插入图片描述

在用Django之前实现用户管理功能,我们先在mysql中写入几条数据:

insert into api_prettynum(mobile,price,level,status)values("111111111",19,1,1);

insert into api_prettynum(mobile,price,level,status)values("18888888888",20,1,1);

insert into api_prettynum(mobile,price,level,status)values("15555555555",22,1,1);

接下来去实现Django靓号管理。

2、靓号列表

同样地,我们采用与部门列表同样的思路来实现用户列表。

1.在urls.py中添加用户列表的路径pretty/list/,并告诉该路径指向的视图view.pretty_list

urls.py

from django.urls import path
from api.views import depart,user,pretty

urlpatterns = [

    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
    path("depart/delete/", depart.depart_delete),
    path("depart/<int:nid>/edit/", depart.depart_edit),

    # 用户管理
    path("user/list/", user.user_list),
    path("user/add/", user.user_add),
    path("user/model/form/add/", user.user_model_form_add),
    path('user/<int:nid>/edit/', user.user_edit),
    path("user/<int:nid>/delete/", user.user_delete),

    # 靓号管理
    path("pretty/list/", pretty.pretty_list),
]

2.在views.py中写出对应的函数,发出请求,并返回响应pretty_list.html

views.py

def pretty_list(request):
    """靓号列表"""

    data_dict = {}
    # 如果是空字典,表示获取所有
    # 不加后面的 "", 首次访问浏览器,搜索框中不会显示前端页面中的 placeholder="Search for..." 属性
    search_data = request.GET.get('query', "")
    if search_data:
        data_dict["mobile__contains"] = search_data

    queryset = PrettyNum.objects.filter(**data_dict).order_by("-level")

    ### 引入封装的 Pagination 类并初始化
    # 初始化
    page_object = Pagination(request, queryset, page_size=10, page_param="page")
    page_queryset = page_object.page_queryset

    # 调用对象的html方法,生成页码
    page_object.html()

    page_string = page_object.page_string
    head_page = page_object.head_page
    end_page = page_object.end_page

    context = {
        "pretty_data": page_queryset,  # 分页的数据
        "search_data": search_data,  # 搜索的内容
        "page_string": page_string,  # 页码
        "head_page": head_page,  # 首页
        "end_page": end_page,  # 尾页
    }

    return render(request, "pretty_list.html", context)

3.创建templates目录下模版html文件pretty_list.html,以此定义部门列表的网页结构和布局。

layout.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--Bootstrap框架-->
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'plugins/font-awesome-4.7.0/css/font-awesome.css' %}">

    <!--datetimepicker插件-->
    <link rel="stylesheet" type="text/css"
          href="{% static 'plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css' %}">
    <style>
        .navbar {
            border-radius: 0;
        }
    </style>
    {% block css %}

    {% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container">

        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">用户管理系统</a>
        </div>

        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li><a href="/depart/list">部门管理</a></li>
                <li><a href="/user/list">用户管理</a></li>
                <li><a href="/pretty/list">靓号管理</a></li>

                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">登录</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">张三 <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">个人资料</a></li>
                        <li><a href="#">我的信息</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">注销</a></li>
                    </ul>
                </li>

            </ul>
        </div>
    </div>
</nav>

<div>
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</div>

{% block js %}
    <script src="{% static 'js/jquery.min.js' %}"></script>
    <!-- 加载 Bootstrap DateTimePicker JS -->
    <script src="{% static 'plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js' %}"></script>
    <script src="{% static 'plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js' %}"></script>
    <script type="text/javascript">
    $(function () {
        //当容器加载完成,对容器调用工具函数
        $("#dt").datetimepicker({
            language: 'zh-CN', //语言
            format: 'yyyy-mm-dd',//日期的格式
            minView: 'month', //可以选择的最小视图
            initialDate: new Date(),//初始化显示的日期
            autoclose: true,//设置选择完日期或者时间之后,日否自动关闭日历
            todayBtn: true,//设置自动显示为今天
            clearBtn: false//设置是否清空按钮,默认为false
        });
    });
    </script>
{% endblock %}

pretty_list.html

{% extends 'layout.html' %}

{% block content %}
<div class="container">

    <div>
        <div style="margin-bottom: 10px; ">
            <a class="btn btn-primary" href="/pretty/add/" target="_blank">新建靓号</a>

            <div style="float: right; width: 300px;">
                <form method="get">
                    <div class="input-group">
                        <input type="text" name="query" class="form-control" placeholder="Search for..."
                            value="{{ search_data }}">
                        <span class="input-group-btn">
                            <button class="btn btn-default" type="submit">
                                <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
                            </button>
                        </span>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;"></span>
                <span>靓号列表</span>
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>号码</th>
                        <th>价格</th>
                        <th>级别</th>
                        <th>状态</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {% for obj in pretty_data %}
                    <tr>
                        <th>{{ obj.id }}</th>
                        <td>{{ obj.mobile }}</td>
                        <td>{{ obj.price }}</td>
                        <td>{{ obj.get_level_display }}</td>
                        <td>{{ obj.get_status_display }}</td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/pretty/{{ obj.id }}/edit/">编辑</a>
                            <a class="btn btn-danger btn-xs" href="/pretty/{{ obj.id }}/delete/">删除</a>
                        </td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
        <div style="display: flex; align-items: center">
            <!-- 页面切换 -->
            <div> <!-- 无需再设置float和宽度 -->
                <ul class="pagination">
                    {{ page_string }}
                </ul>
            </div>
            <!-- 输入页码框 -->
            <div style="width: 200px;margin-bottom: 5px"> <!-- 保持输入框宽度,但不需要float:right -->
                <form method="get">
                    <div class="input-group">
                        <input type="text" name="page" class="form-control" placeholder="页码">
                        <span class="input-group-btn">
                    <button class="btn btn-default" type="submit">跳转</button>
                </span>
                    </div>
                </form>
            </div>
        </div>
{% endblock %}

效果:

image-20240314112640113

3、新建靓号

同样地采用ModelForm组件来实现。

1.在urls.py中添加用户列表的路径pretty/add/,并告诉该路径指向的视图view.pretty_add

urls.py

 from django.urls import path
 from api.views import depart,user,pretty
 
 urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
    path("depart/delete/", depart.depart_delete),
    path("depart/<int:nid>/edit/", depart.depart_edit),

    # 用户管理
    path("user/list/", user.user_list),
    path("user/add/", user.user_add),
    path("user/model/form/add/", user.user_model_form_add),
    path('user/<int:nid>/edit/', user.user_edit),
    path("user/<int:nid>/delete/", user.user_delete),

    # 靓号管理
    path("pretty/list/", pretty.pretty_list),
    path("pretty/add/", pretty.pretty_add),
 ]
 

2.在views.py中写出对应的函数,发出请求,并返回响应pretty_add.html

views.py

class PrettyModelForm(BootStrapModelForm):
    # 验证:方式1
    mobile = forms.CharField(
        label="手机号",
        validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误'), ],
    )

    class Meta:
        model = models.PrettyNum
        # fields = "__all__"
        # exclude = ['level']
        fields = ["mobile", 'price', 'level', 'status']

    # 验证:方式2
    def clean_mobile(self):
        txt_mobile = self.cleaned_data["mobile"]

        exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()
        if exists:
            raise ValidationError("手机号已存在")

        # 验证通过,用户输入的值返回
        return txt_mobile
    
def pretty_add(request):
    """添加靓号"""
    if request.method == "GET":
        form = PrettyModelForm()
        return render(request, "pretty_add.html", {"form": form})
    form = PrettyModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        return redirect('/pretty/list/')
    return render(request, 'pretty_add.html', {"form": form})

3.创建templates目录下模版html文件pretty_add.html,以此实现用户信息的新增。

pretty_add.html

{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title" style="font-weight: bold">新建靓号</h3>
            </div>
            <div class="panel-body">
                <form method="post" 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 %}
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-primary">提 交</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock %}
<form method="post">
    {% csrf_token %}
    {% for field in form %}
        {{ field.label }} : {{ field }}
    {% endfor %}
</form>

效果:

image-20240314113136689

4、编辑靓号

在完成新建靓号后我们来接着实现编辑靓号。

①编辑靓号

1.在urls.py中添加用户列表的路径pretty/<int:nid>/edit/,并告诉该路径指向的视图view.pretty_edit

urls.py

 from django.urls import path
 from api.views import depart,user,pretty
 
 urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
    path("depart/delete/", depart.depart_delete),
    path("depart/<int:nid>/edit/", depart.depart_edit),

    # 用户管理
    path("user/list/", user.user_list),
    path("user/add/", user.user_add),
    path("user/model/form/add/", user.user_model_form_add),
    path('user/<int:nid>/edit/', user.user_edit),
    path("user/<int:nid>/delete/", user.user_delete),

    # 靓号管理
    path("pretty/list/", pretty.pretty_list),
    path("pretty/add/", pretty.pretty_add),
    path("pretty/<int:nid>/edit/", pretty.pretty_edit),
 ]
 

2.在views.py中写出对应的函数,发出请求,并返回响应pretty_edit.html

views.py

def pretty_edit(request, nid):
    """ 编辑靓号 """
    row_object = models.PrettyNum.objects.filter(id=nid).first()

    if request.method == "GET":
        form = PrettyEditModelForm(instance=row_object)
        return render(request, 'pretty_edit.html', {"form": form})

    form = PrettyEditModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        form.save()
        return redirect('/pretty/list/')

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

3.创建templates目录下模版html文件pretty_edit.html,以此实现用户信息的新增。

pretty_edit.html

{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title" style="font-weight: bold">编辑靓号</h3>
            </div>
            <div class="panel-body">
                <form method="post" 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 %}
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-primary">提 交</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

效果:

image-20240314120644463

②手机号重复问题

在添加和编辑时,遇到手机号重复的我们应该不能再进行添加或编辑,因此我们可以使用以下方式来解决手机号重复问题,对于:

  • 添加:若手机号已经存在,提示"手机号已存在"。

  • 编辑:若手机号及当前手机号本身以外已存在,提示"手机号已存在"。

我们可以考虑在class PrettyModelForm也就是靓号ModelForm类里添加以下代码:

def clean_mobile(self):
    txt_mobile = self.cleaned_data['mobile']

    if len(txt_mobile) != 11:
        # 验证不通过
        raise ValidationError('格式错误')

    exists_data = PrettyNum.objects.filter(mobile=txt_mobile).exists()
    if exists_data:
        raise ValidationError("手机号已存在")

    # 验证通过
    return txt_mobile

整合之后,可以这样写:

image-20240314120951690

class PrettyModelForm(BootStrapModelForm):
    # 验证:方式1
    mobile = forms.CharField(
        label="手机号",
        validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误'), ],
    )

    class Meta:
        model = models.PrettyNum
        # fields = "__all__"
        # exclude = ['level']
        fields = ["mobile", 'price', 'level', 'status']

    # 验证:方式2
    def clean_mobile(self):
        txt_mobile = self.cleaned_data["mobile"]

        exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()
        if exists:
            raise ValidationError("手机号已存在")

        # 验证通过,用户输入的值返回
        return txt_mobile

效果:

121

5、删除靓号

与上述步骤相仿,我们继续来实现删除靓号,删除靓号的基础是建立在靓号列表的实现和新增靓号的功能之上的。

1.在urls.py中添加用户列表的路径pretty/<int:nid>/delete/,并告诉该路径指向的视图view.pretty_delete

urls.py

 from django.urls import path
 from api.views import depart,user,pretty
 
 urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
    path("depart/delete/", depart.depart_delete),
    path("depart/<int:nid>/edit/", depart.depart_edit),

    # 用户管理
    path("user/list/", user.user_list),
    path("user/add/", user.user_add),
    path("user/model/form/add/", user.user_model_form_add),
    path('user/<int:nid>/edit/', user.user_edit),
    path("user/<int:nid>/delete/", user.user_delete),

    # 靓号管理
    path("pretty/list/", pretty.pretty_list),
    path("pretty/add/", pretty.pretty_add),
    path("pretty/<int:nid>/edit/", pretty.pretty_edit),
    path("pretty/<int:nid>/delete/", pretty.pretty_delete),
 ]
 

2.在views.py中写出对应的函数,发出请求,并返回响应pretty_list.html

views.py

def pretty_delete(request, nid):
    models.PrettyNum.objects.filter(id=nid).delete()
    return redirect('/pretty/list/')

3.操作templates目录下模版html文件user_list.html,以此实现用户信息的删除。

pretty_list.html

{% extends 'layout.html' %}

{% block content %}
<div class="container">

    <div>
        <div style="margin-bottom: 10px; ">
            <a class="btn btn-primary" href="/pretty/add/" target="_blank">新建靓号</a>

            <div style="float: right; width: 300px;">
                <form method="get">
                    <div class="input-group">
                        <input type="text" name="query" class="form-control" placeholder="Search for..."
                            value="{{ search_data }}">
                        <span class="input-group-btn">
                            <button class="btn btn-default" type="submit">
                                <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
                            </button>
                        </span>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;"></span>
                <span>靓号列表</span>
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>号码</th>
                        <th>价格</th>
                        <th>级别</th>
                        <th>状态</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {% for obj in pretty_data %}
                    <tr>
                        <th>{{ obj.id }}</th>
                        <td>{{ obj.mobile }}</td>
                        <td>{{ obj.price }}</td>
                        <td>{{ obj.get_level_display }}</td>
                        <td>{{ obj.get_status_display }}</td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/pretty/{{ obj.id }}/edit/">编辑</a>
                            <a class="btn btn-danger btn-xs" href="/pretty/{{ obj.id }}/delete/">删除</a>
                        </td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
        <div style="display: flex; align-items: center">
            <!-- 页面切换 -->
            <div> <!-- 无需再设置float和宽度 -->
                <ul class="pagination">
                    {{ page_string }}
                </ul>
            </div>
            <!-- 输入页码框 -->
            <div style="width: 200px;margin-bottom: 5px"> <!-- 保持输入框宽度,但不需要float:right -->
                <form method="get">
                    <div class="input-group">
                        <input type="text" name="page" class="form-control" placeholder="页码">
                        <span class="input-group-btn">
                    <button class="btn btn-default" type="submit">跳转</button>
                </span>
                    </div>
                </form>
            </div>
        </div>
{% endblock %}

效果:

image-20240314121746634

整体效果:

122

6、靓号搜索

在实现了上述基础模块功能后,新增一个搜索的功能,那该怎么实现呢?

filter()筛选方法可以帮助我们实现,例如:

# models.PrettyNum.objects.filter()用于从数据库中查询符合特定条件的记录
models.PrettyNum.objects.filter("18812345678",id=123)

data_dict = {"mobile":"18821213246","id"=123}
models.PrettyNum.objects.filter(**data_dict)
# 等于12
models.PrettyNum.objects.filter(id=12)
# 大于12
models.PrettyNum.objects.filter(id__gt=12)
# 大于等于12
models.PrettyNum.objects.filter(id__gte=12)
# 小于12
models.PrettyNum.objects.filter(id__lt=12)
# 小于等于12
models.PrettyNum.objects.filter(id__lte=12)

data_dict = {"id__lte":12}
models.PrettyNum.objects.filter(**data_dict)
# 筛选出等于152的
models.PrettyNum.objects.filter(mobile="152")
# 筛选出以152开头的
models.PrettyNum.objects.filter(mobile__startwith="152")
# 筛选出以765结尾的
models.PrettyNum.objects.filter(mobile__endswith="765")
# 筛选出包含666的
models.PrettyNum.objects.filter(mobile__contains="666")

data_dict = {"mobile_contains":"999"}
models.PrettyNum.objects.filter(**data_dict)

紧接着我们来实现这个功能:

修改views.py视图函数中的pretty_list:

def pretty_list(request):
    """靓号列表"""

    data_dict = {}
    # 如果是空字典,表示获取所有
    # 不加后面的 "", 首次访问浏览器,搜索框中不会显示前端页面中的 placeholder="Search for..." 属性
    search_data = request.GET.get('query', "")
    if search_data:
        data_dict["mobile__contains"] = search_data

    queryset = PrettyNum.objects.filter(**data_dict).order_by("-level")

    ### 引入封装的 Pagination 类并初始化
    # 初始化
    page_object = Pagination(request, queryset, page_size=10, page_param="page")
    page_queryset = page_object.page_queryset

    # 调用对象的html方法,生成页码
    page_object.html()

    page_string = page_object.page_string
    head_page = page_object.head_page
    end_page = page_object.end_page

    context = {
        "pretty_data": page_queryset,  # 分页的数据
        "search_data": search_data,  # 搜索的内容
        "page_string": page_string,  # 页码
        "head_page": head_page,  # 首页
        "end_page": end_page,  # 尾页
    }

    return render(request, "pretty_list.html", context)

修改pretty_list.html:

{% extends 'layout.html' %}

{% block content %}
<div class="container">

    <div>
        <div style="margin-bottom: 10px; ">
            <a class="btn btn-primary" href="/pretty/add/" target="_blank">新建靓号</a>

            <div style="float: right; width: 300px;">
                <form method="get">
                    <div class="input-group">
                        <input type="text" name="query" class="form-control" placeholder="Search for..."
                            value="{{ search_data }}">
                        <span class="input-group-btn">
                            <button class="btn btn-default" type="submit">
                                <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
                            </button>
                        </span>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;"></span>
                <span>靓号列表</span>
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>号码</th>
                        <th>价格</th>
                        <th>级别</th>
                        <th>状态</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {% for obj in pretty_data %}
                    <tr>
                        <th>{{ obj.id }}</th>
                        <td>{{ obj.mobile }}</td>
                        <td>{{ obj.price }}</td>
                        <td>{{ obj.get_level_display }}</td>
                        <td>{{ obj.get_status_display }}</td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/pretty/{{ obj.id }}/edit/">编辑</a>
                            <a class="btn btn-danger btn-xs" href="/pretty/{{ obj.id }}/delete/">删除</a>
                        </td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
        <div style="display: flex; align-items: center">
            <!-- 页面切换 -->
            <div> <!-- 无需再设置float和宽度 -->
                <ul class="pagination">
                    {{ page_string }}
                </ul>
            </div>
            <!-- 输入页码框 -->
            <div style="width: 200px;margin-bottom: 5px"> <!-- 保持输入框宽度,但不需要float:right -->
                <form method="get">
                    <div class="input-group">
                        <input type="text" name="page" class="form-control" placeholder="页码">
                        <span class="input-group-btn">
                    <button class="btn btn-default" type="submit">跳转</button>
                </span>
                    </div>
                </form>
            </div>
        </div>
{% endblock %}

效果:

123

7、分页切换

要想实现分页跳转切换,要明白它的原理,分页首先要得出总页数,划分好每页的数量,比如10或20,拿总页数除以10或20,最终得到页数,然后再设计跳转的功能,此时比如page=1到page=2,此时我们可以通过操作点击对应的页码,进而实现page+1来实现。在具体实现它之前先了解一些简要的操作,假如每页10个,我们该如何将这10个提取出来?

queryset = models.PrettyNum.objects.all()

queryset = models.PrettyNum.objects.filter(id=1)[0:10]
# 第1页
queryset = models.PrettyNum.objects.all()[0:10]
# 第2页
queryset = models.PrettyNum.objects.all()[10:20]
# 第3页
queryset = models.PrettyNum.objects.all()[20:30]
data = models.PrettyNum.objects.all().count()
data = models.PrettyNum.objects.filter(id=1).count()
  • 分页的逻辑和处理规则
def pretty_list(request):
    # """靓号列表"""

    # for i in range(300):
    #     models.PrettyNum.objects.create(mobile="18811899006",price=10,level=1,status=1)

    data_dict = {}
    search_data = request.GET.get("q", "")

    if search_data:
        data_dict["mobile__contains"] = search_data


    queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")

    page_object = Pagination(request)
    page_queryset = page_object.page_queryset

    # 1.根据用户想要访问的页码,计算出起始和终止位置
    # page = int(request.GET.get('page', 1))
    # page_size = 10  # 每页显示10条数据
    # start = (page - 1) * page_size
    # end = page * page_size

    # 数据总条数
    total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-level").count()

    # 总页码
    total_page_count, div = divmod(total_count, page_size)
    if div:
        total_page_count += 1

    # 计算出,显示出当前页的前5页和后5页
    plus = 5
    if total_page_count <= 2 * plus + 1:
        # 数据库中的数据比较少,都没有达到11页
        start_page = 1
        end_page = total_page_count
    else:
        # 数据库中的数据较多,大于11页

        # 当前页小于5时(小极值)
        if page <= plus:
            start_page = 1
            end_page = 2 * plus + 1
        else:
            # 当前页大于5时
            # 当前页+5 > 总页面
            if (page + plus) > total_page_count:
                start_page = total_page_count - 2 * plus
                end_page = total_page_count
            else:
                start_page = page - plus
                end_page = page + plus + 1

    # 页码
    page_str_list = []

    # 首页
    page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))

    # 上一页
    if page > 1:
        prev = '<li><a href="?page={}">上一页</a></li>'.format(page-1)
    else:
        prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
    page_str_list.append(prev)


    for i in range(start_page, end_page + 1):
        if i == page:
            ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
        else:
            ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
        page_str_list.append(ele)

    # 下一页
    if page < total_page_count:
        prev = '<li><a href="?page={}">下一页</a></li>'.format(page+1)
    else:
        prev = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
    page_str_list.append(prev)

    # 首页
    page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count))

    page_string = mark_safe("".join(page_str_list))

    page_number = request.GET.get('page', 1)  # 获取页码,默认为1
    paginator = Paginator(queryset, 10)  # 假设每页显示10条数据

    try:
        page_obj = paginator.page(page_number)
    except PageNotAnInteger:
        # 如果页码不是一个整数,则显示第一页
        page_obj = paginator.page(1)
    except EmptyPage:
        # 如果页码超出范围,则显示最后一页
        page_obj = paginator.page(paginator.num_pages)

    search_string = """"""
    page_str_list.append(search_string)

    return render(request, 'pretty_list.html',
                  {'queryset': queryset, "search_data": search_data, "page_string": page_string,'page_obj': page_obj})

在实现了上述逻辑之后,虽然代码难度不高,但是难免过于繁琐,那么该怎么灵活地利用它呢?

可以对它分页类封装,这样以后再遇到要写分页的时候,我们只需要调用它稍加修改就好:

新建文件夹utils,并新建pagination.py文件以存放它:

image-20240314124021506

pagination.py

"""
自定义的分页组件

"""

from django.utils.safestring import mark_safe
import copy


class Pagination(object):
    def __init__(self, request, queryset, page_size=10, page_param="page", page_show=5):
        """
        :param request: 请求的对象
        :param queryset: 符合条件的数据(根据此数据进行分页处理)
        :param page_size: 每页显示多少条数据
        :param page_param: 获取在URL中传递的分页参数, 例如: /pretty/list/?page=21
        :param page_show: 页码显示前几页后几页
        """

        # 防止搜索出结果进行翻页时,URL参数没有了搜索参数
        query_dict = copy.deepcopy(request.GET)
        query_dict._mutable = True
        self.query_dict = query_dict

        self.page_param = page_param

        page = int(request.GET.get(page_param, 1))

        # 如果不是整数
        if type(page) != int:
            # 强制让页码为1
            page = 1

        self.page = page

        self.start = (page - 1) * page_size
        self.end = page * page_size

        # 每页展示的数据行数
        self.page_queryset = queryset[self.start:self.end]

        total_data_count = queryset.count()     # 数据行数
        total_page_count, div = divmod(total_data_count, page_size)
        if div:
            total_page_count += 1
        self.total_page_count = total_page_count    # 总页码数量
        self.page_show = page_show  # 当前页前后展示的页码数量
        self.request = request

    def html(self):
        # 如果总页码数量大于 11
        if self.total_page_count > self.page_show * 2 + 1:
            # 如果当前页面页码位置小于等于5
            if self.page <= 5:
                start_page = 1
                end_page = self.page_show * 2 + 2
            # 否则,当前页面页码位置大于5时
            else:
                # 防止页码超出范围
                if self.page >= self.total_page_count - self.page_show:
                    start_page = self.total_page_count - self.page_show * 2
                    end_page = self.total_page_count + 1
                else:
                    # 计算出当前页的前5页和后5页
                    start_page = self.page - self.page_show
                    end_page = self.page + self.page_show + 1

        else:
            start_page = 1
            end_page = self.total_page_count + 1

        ######## 创建页码 ########
        # 页码
        page_str_list = []

        # self.query_dict.setlist(self.page_param, [1])
        # page_str_list.append('<li><a href="?page={}">{}</a></li>'.format(self.query_dict.urlencode()))

        # 跳到首页
        self.query_dict.setlist(self.page_param, [1])
        self.head_page = '<li><a href="?{}" aria-label="Previous"><span aria-hidden="true">首页</span></a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(self.head_page)

        # 跳到上10页
        # 如果当前页面小于 11, 防止超过最小页数
        if self.page < self.page_show * 2 + 1:
            self.query_dict.setlist(self.page_param, [1])
            prev = '<li><a href="?{}">{}</a></li>'.format(
                self.query_dict.urlencode(), "<<")
            page_str_list.append(prev)
        else:
            self.query_dict.setlist(self.page_param, [self.page - 10])
            prev = '<li><a href="?{}">{}</a></li>'.format(
                self.query_dict.urlencode(), "<<")
            page_str_list.append(prev)

        for i in range(start_page, end_page):
            # 如果是当前页,高亮显示页码颜色
            if self.page == i:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li class="active"><a href="?{}">{}</a></li>'.format(
                    self.query_dict.urlencode(), i)
            else:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li><a href="?{}">{}</a></li>'.format(
                    self.query_dict.urlencode(), i)
            page_str_list.append(ele)

        # 跳到下10页
        # 如果当前页面页数 大于 最大页面数量减去(page_show*2+1),则直接跳到最后一页,防止超过最大页数
        if self.page >= self.total_page_count - self.page_show * 2 + 1:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            next = '<li><a href="?{}">{}</a></li>'.format(
                self.query_dict.urlencode(), ">>")
            page_str_list.append(next)
        else:
            self.query_dict.setlist(self.page_param, [self.page + 10])
            next = '<li><a href="?page={}">{}</a></li>'.format(
                self.query_dict.urlencode(), ">>")
            page_str_list.append(next)

        # 跳到尾页
        self.query_dict.setlist(self.page_param, [self.total_page_count])
        self.end_page = '<li><a href="?{}" aria-label="Next"><span aria-hidden="true">尾页</span></a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(self.end_page)

        self.page_string = mark_safe("".join(page_str_list))

124

8、优化(整合分类)

①拆分views.py

由上面可以看到,上面部分内容有些杂乱,因此我们可以将views.py 换成 views目录,将views.py拆成depart.py、user.py、pretty.py,这样区分更鲜明,更易于管理

1.depart.py

# -*- coding: utf-8 -*-            
# @Time : 2024-03-13 21:39
from django.shortcuts import render, redirect
from api import models
from api.utils.pagination import Pagination


def depart_list(request):
    """部门列表"""
    queryset = models.Department.objects.all()

    page_object = Pagination(request, queryset, page_size=2)
    page_object.html()

    context = {
        "queryset": page_object.page_queryset,
        "page_string": page_object.page_string,
    }
    return render(request, 'depart_list.html', context)

def depart_add(request):
    """添加部门"""
    if request.method == "GET":
        return render(request, 'depart_add.html')

    # 获取用户POST提交过来的数据(title输入为空)
    title = request.POST.get("title")

    # 保存到数据库
    models.Department.objects.create(title=title)

    # 重定向回部门列表
    return redirect("/depart/list/")

def depart_delete(request):
    """删除部门"""
    # 获取ID
    # http://127.0.0.1:8000/depart/delete/?nid=1
    nid = request.GET.get('nid')

    models.Department.objects.filter(id=nid).delete()
    # 重定向回部门列表
    return redirect("/depart/list")

def depart_edit(request, nid):
    """修改部门"""
    if request.method == "GET":
        # 根据nid,获取他的数据[obj,]
        row_object = models.Department.objects.filter(id=nid).first()
        return render(request, 'depart_edit.html', {"row_object": row_object})
    # 获取用户的标题
    title = request.POST.get("title")
    # 根据ID找到数据库中的数据进行更新
    models.Department.objects.filter(id=nid).update(title=title)
    # 重定向回部门列表
    return redirect("/depart/list/")

2.user.py

# -*- coding: utf-8 -*-            
# @Time : 2024-03-13 21:39
from django.shortcuts import render, redirect
from api import models
from api.models import UserInfo
from api.utils.pagination import Pagination
from api.utils.form import UserModelForm


def user_list(request):
    """用户列表"""
    # 获取所有用户列表
    queryset = UserInfo.objects.all()

    page_object = Pagination(request, queryset, page_size=3)

    # 用 python 的语法获取数据
    """
    for obj in user_data:
        # obj.get_gender_display() 表示匹配 男/女,原始字段名为gender,obj.get_字段名称_display()
        # obj.create_time.strftime("%Y-%m-%d") 表示将时间格式转换成固定格式的字符串
        # obj.depart.title 表示获取depart_id对应的部门名称,因为我们在models中定义表时与另外一张表设置了级联关系,有外键
        print(obj.id, obj.name, obj.password, obj.age, obj.account, obj.get_gender_display(), obj.depart.title, obj.create_time.strftime("%Y-%m-%d"))
    """

    page_object.html()

    context = {
        "queryset": page_object.page_queryset,
        "page_string": page_object.page_string,
    }

    return render(request, "user_list.html", context)


def user_add(request):
    """添加用户(原始方式)"""
    if request.method == "GET":
        context = {
            'gender_choices': models.UserInfo.gender_choices,
            'depart_list': models.Department.objects.all(),
        }
        return render(request, 'user_add.html', context)
    # 获取用户提交的数据
    user = request.POST.get('name')
    pwd = request.POST.get('pwd')
    age = request.POST.get('age')
    account = request.POST.get('ac')
    ctime = request.POST.get('ctime')
    gender = request.POST.get('gd')
    depart_id = request.POST.get('dp')

    # 添加到数据库中国
    models.UserInfo.objects.create(name=user, password=pwd, age=age, account=account, creat_time=ctime, gender=gender,
                                   depart_id=depart_id)

    # 返回到用户列表页面
    return redirect("/user/list/")


def user_model_form_add(request):
    """添加用户(ModelForm版本)"""
    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/")

    # 校验失败(在页面上显示错误信息)
    return render(request, "user_model_form_add.html", {"form": form})


def user_edit(request, nid):
    """编辑用户"""
    row_obj = UserInfo.objects.filter(id=nid).first()

    # GET请求
    if request.method == "GET":
        form = UserModelForm(instance=row_obj)
        return render(request, "user_edit.html", {"form": form})

    # POST请求
    form = UserModelForm(data=request.POST, instance=row_obj)
    if form.is_valid():
        form.save()
        return redirect("/user/list/")

    return render(request, "user_edit.html", {"form": form})


def user_delete(request, nid):
    models.UserInfo.objects.filter(id=nid).delete()
    return redirect('/user/list/')

3.pretty.py

# -*- coding: utf-8 -*-            
# @Time : 2024-03-13 21:39
from django import forms
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from api import models
from api.models import PrettyNum, UserInfo
from api.utils.pagination import Pagination
from api.utils.form import UserModelForm, PrettyModelForm, PrettyEditModelForm


def pretty_list(request):
    """靓号列表"""

    data_dict = {}
    # 如果是空字典,表示获取所有
    # 不加后面的 "", 首次访问浏览器,搜索框中不会显示前端页面中的 placeholder="Search for..." 属性
    search_data = request.GET.get('query', "")
    if search_data:
        data_dict["mobile__contains"] = search_data

    queryset = PrettyNum.objects.filter(**data_dict).order_by("-level")

    ### 引入封装的 Pagination 类并初始化
    # 初始化
    page_object = Pagination(request, queryset, page_size=10, page_param="page")
    page_queryset = page_object.page_queryset

    # 调用对象的html方法,生成页码
    page_object.html()

    page_string = page_object.page_string
    head_page = page_object.head_page
    end_page = page_object.end_page

    context = {
        "pretty_data": page_queryset,  # 分页的数据
        "search_data": search_data,  # 搜索的内容
        "page_string": page_string,  # 页码
        "head_page": head_page,  # 首页
        "end_page": end_page,  # 尾页
    }

    return render(request, "pretty_list.html", context)


def pretty_add(request):
    """添加靓号"""
    if request.method == "GET":
        form = PrettyModelForm()
        return render(request, "pretty_add.html", {"form": form})
    form = PrettyModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        return redirect('/pretty/list/')
    return render(request, 'pretty_add.html', {"form": form})


def pretty_edit(request, nid):
    """ 编辑靓号 """
    row_object = models.PrettyNum.objects.filter(id=nid).first()

    if request.method == "GET":
        form = PrettyEditModelForm(instance=row_object)
        return render(request, 'pretty_edit.html', {"form": form})

    form = PrettyEditModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        form.save()
        return redirect('/pretty/list/')

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


def pretty_delete(request, nid):
    models.PrettyNum.objects.filter(id=nid).delete()
    return redirect('/pretty/list/')

新手保护期,views可拆分,尽量先别拆models.py,一般平时够用。

②ModelForm优化

将三个单独定义的类

class UserModelForm(forms.ModelForm):
class PrettyModelForm(forms.ModelForm):
class PrettyEditModelForm(forms.ModelForm):

改为继承自同一个自定义类,这样做的好处在于,以后再有其它类,常规的部分不需要再重复定义,直接从父类获取即可:

class UserModelForm(BootStrapModelForm):
class PrettyModelForm(BootStrapModelForm):
class PrettyEditModelForm(BootStrapModelForm):

将自定义类放在utils目录下新建的bootstrap.py中:

class BootStrapModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 循环ModelForm中的所有字段,给每个字段的插件设置
        for name, field in self.fields.items():
            # 字段中有属性,保留原来的属性,没有属性,才增加。
            if field.widget.attrs:
                field.widget.attrs["class"] = "form-control"
                field.widget.attrs["placeholder"] = field.label
            else:
                field.widget.attrs = {
                    "class": "form-control",
                    "placeholder": field.label
                }

③整合Form

将三个类整合到一起,放在utils目录下新建的form.py中

from api import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django import forms
from api.utils.bootstrap import BootStrapModelForm


class UserModelForm(BootStrapModelForm):
    name = forms.CharField(
        min_length=3,
        label="用户名",
        widget=forms.TextInput(attrs={"class": "form-control"})
    )

    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", 'account', 'creat_time', "gender", "depart"]


class PrettyModelForm(BootStrapModelForm):
    # 验证:方式1
    mobile = forms.CharField(
        label="手机号",
        validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误'), ],
    )

    class Meta:
        model = models.PrettyNum
        # fields = "__all__"
        # exclude = ['level']
        fields = ["mobile", 'price', 'level', 'status']

    # 验证:方式2
    def clean_mobile(self):
        txt_mobile = self.cleaned_data["mobile"]

        exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()
        if exists:
            raise ValidationError("手机号已存在")

        # 验证通过,用户输入的值返回
        return txt_mobile


class PrettyEditModelForm(BootStrapModelForm):
    # mobile = forms.CharField(disabled=True, label="手机号")
    mobile = forms.CharField(
        label="手机号",
        validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误'), ],
    )

    class Meta:
        model = models.PrettyNum
        fields = ['mobile', 'price', 'level', 'status']

    # 验证:方式2
    def clean_mobile(self):
        # 当前编辑的哪一行的ID
        # print(self.instance.pk)
        txt_mobile = self.cleaned_data["mobile"]
        exists = models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists()
        if exists:
            raise ValidationError("手机号已存在")

        # 验证通过,用户输入的值返回
        return txt_mobile

效果:

125

优化后,仍然能达到相同的效果,区别在于,后者更加整齐,分类更清晰。

关于靓号管理的实现就到这里,后续会继续实现管理员管理、账户登录、以及Ajax等,并及时更新博客,敬请期待。

很感谢你能看到这里,如有相关疑问,还请下方评论留言。
Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
希望本篇内容能对大家有所帮助,如果大家喜欢的话,请动动手点个赞和关注吧,非常感谢你们的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/457477.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【探索Linux】—— 强大的命令行工具 P.27(网络编程套接字 —— UDP协议介绍 | TCP协议介绍 | UDP 和 TCP 的异同)

阅读导航 引言一、UDP协议1. UDP简介2. UDP的特点3. UDP的使用场景4. UDP的局限性 二、TCP协议1. TCP简介2. TCP的特点3. TCP的应用场景 三、UDP 和 TCP 的异同温馨提示 引言 在上一篇文章中&#xff0c;我们深入探讨了Linux网络编程的基石——套接字&#xff08;Socket&#…

微博热搜榜单采集,微博热搜榜单爬虫,微博热搜榜单解析,完整代码(话题榜+热搜榜+文娱榜和要闻榜)

文章目录 代码1. 话题榜2. 热搜榜3. 文娱榜和要闻榜 过程1. 话题榜2. 热搜榜3. 文娱榜和要闻榜 代码 1. 话题榜 import requests import pandas as pd import urllib from urllib import parse headers { authority: weibo.com, accept: application/json, text/pl…

黑马程序员java部分笔记(持续更新)十点二:封装

面向对象的三大特征&#xff1a;封装&#xff0c;继承&#xff0c;多态 告诉我们正确的属性与方法 例1&#xff1a;需求&#xff1a;定义一个类&#xff1a;人 属性&#xff1a;姓名&#xff0c;年龄 行为&#xff1a;吃饭&#xff0c;睡觉 代码&#xff1a; public class Pe…

IDEA中导入eclipse运行的java项目

本篇文章主要的内容是在IDEA中导入eclipse运行的java项目&#xff0c;亲测有效。 话不多说&#xff0c;直接开整。 前提&#xff1a;先打开idea软件&#xff0c;界面如下&#xff1a; 开始按下方步骤依次走即可。 1、file --> new --> Project from Existing Sources..…

el-input设置max、min无效的解决方案

目录 一、方式1&#xff1a;type“number” 二、方式2&#xff1a;oninput&#xff08;推荐&#xff09; 三、计算属性 如下表所示&#xff0c;下面为官方关于max&#xff0c;min的介绍&#xff1a; el-input&#xff1a; max原生属性&#xff0c;设置最大值min原生属性&a…

函数栈和调用

我们看函数调用&#xff0c;首先明确&#xff0c;ra是存着返回地址&#xff0c;s0是帧指针&#xff0c; addi函数一开始先开辟栈空间&#xff08;改变sp&#xff09; 然后存下ra和s0 然后把s0指向栈底部&#xff0c;然后利用s0来吧局部变量存放再栈上&#xff0c;然后又放进…

Android 异常重启--踩坑归来--干货篇

如果你未对自己的app进行过处理&#xff0c;那么线上各种偶发莫名其妙的闪退、白屏、数据丢失&#xff0c;请检查一下是否因此而引发的。 起因 异常重建指的是非配置变更情况下导致的 Activity 重新创建。 常见场景大多是因为内存等资源不足&#xff0c;从而导致后台应用被系…

大模型笔记:吴恩达 ChatGPT Prompt Engineering for Developers(1) prompt的基本原则和策略

1 intro 基础大模型 VS 用指令tune 过的大模型 基础大模型 只会对prompt的文本进行续写 所以当你向模型发问的时候&#xff0c;它往往会像复读机一样续写几个问题这是因为在它见过的语料库文本&#xff08;通常大多来自互联网&#xff09;中&#xff0c;通常会连续列举出N个问…

【软考】UML中的图之对象图

目录 1. 说明2. 图示3. 特性 1. 说明 1.对象图即object diagram2.展现了某一时刻一组对象以及它们之间的关系3.描述了在类图中所建立的事物的实例的静态快照4.对象图一般包括对象和链5.对象图展示的是对象之间关系&#xff0c;不存在交互&#xff0c;所以不是交互图 2. 图示 …

【FPGA】DDR3学习笔记(二)丨从SDRAM到DDR3的IP核设计

本篇文章包含的内容 一、DDR SDRAM1.1 基本概述1.2 工作时序&#xff08;以读取为例&#xff09; 二、DDR2 SDRAM2.1 基本概述2.2 工作时序 三、DDR3 SDRAM3.1 基本概述3.2 硬件设计3.3 读写时序3.4 MIG IP核设计3.5 读写代码设计 开发板&#xff1a;正点原子的达芬奇开发板&am…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:GridCol)

栅格子组件&#xff0c;必须作为栅格容器组件(GridRow)的子组件使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含单个子组件。 接口 GridCol(option?:{span?: number | …

#QT(一种朴素的计算器实现方法)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;这是全靠自己想法写的计算器&#xff0c;没有参考任何教程。 &#xff08;1&#xff09;这个计算器只要有运算符敲入就会进行一次运算&#xff0c;所以他没有先后之后&#xff0c;无法满足运算优先级。 &#xff08;2&#xff…

linux安全--Nginx与Tomcat实现负载均衡

目录 1.实验拓扑原理图&#xff0c;前提实现全网互通 2.找到nginx的conf目录中的nginx.conf文件 3.实验效果 1.实验拓扑原理图&#xff0c;前提实现全网互通 搭建全网互通可以看https://blog.csdn.net/m0_74313947/article/details/136008513?spm1001.2014.3001.5501 搭建N…

JavaEE之多线程(创建线程的五种写法)详解

&#x1f63d;博主CSDN主页: 小源_&#x1f63d; &#x1f58b;️个人专栏: JavaEE &#x1f600;努力追逐大佬们的步伐~ 目录 1. 前言 2. 操作系统"内核" 3. 创建线程的五种写法 (我们重点要掌握最后一种写法!!) 3.1 继承 Thread, 重写 run 3. 2 实现 Runnabl…

北京保险服务中心携手镜舟科技,助推新能源车险市场规范化

2022 年&#xff0c;一辆新能源汽车在泥泞的小路上不慎拖底&#xff0c;动力电池底壳受损&#xff0c;电池电量低。车主向保险公司报案&#xff0c;希望能够得到赔偿。然而&#xff0c;在定损过程中&#xff0c;保司发现这辆车的电池故障并非由拖底事件引起&#xff0c;而是由于…

电脑坏了去维修,第一家报价800,第三家说报废!

这篇文章主要讲的是修理坏掉的电脑。 第一家报价300&#xff0c;第二家报价800&#xff0c;第三家说要报废&#xff01; 相信很多朋友对于修电脑坏了要多少钱有很多困惑&#xff0c;修电脑坏了要多少钱&#xff0c;到底去正规售后服务还是去非品牌店维修一台坏掉的电脑。 今天高…

基于单片机的电子琴设计

基于单片机的电子琴设计 摘 要 读书、看电影、听音乐&#xff0c;都是最常见的丰富内心世界的良剂。听音乐&#xff0c;作为陶冶情操、提升境界最便捷的方式&#xff0c;正受到越来越多人们的欢迎。音乐可以很轻松的融入各种场合&#xff0c;给人们带来很轻松的氛围&#xff…

基础---nginx 启动不了,跟 Apache2 服务冲突

文章目录 查看 nginx 服务状态nginx 启动后 访问页面 127.0.0.1停止 nginx 服务&#xff0c;访问不了页面停止/启动 Apache2 服务&#xff0c;启动 Apache2 页面访问显示正确nginx 莫名启动不了卸载 Apache2 服务器 启动 nginx &#xff0c;但是总是不能实现反向代理&#xff0…

微服务分布式springcloud的体育场地预约系统演kdm1z

体育场馆设施预约系统是在实际应用和软件工程的开发原理之上&#xff0c;运用java语言以及Springcloud框架进行开发。首先要进行需求分析&#xff0c;分析出体育场馆设施预约系统的主要功能&#xff0c;然后设计了系统结构。整体设计包括系统的功能、系统总体结构、系统数据结构…

Annaconda环境下ChromeDriver配置及爬虫编写

Anaconda环境的chromedriver安装配置_anaconda 配置chromedriver-CSDN博客 Chromedriver驱动( 121.0.6167.85 ) - 知乎 下载好的驱动文件解压&#xff0c;将exe程序复制到Annaconda/Scripts目录以及Chrome/Application目录下 注意要提前pip install selenium包才能运行成功&a…