网站搭建基本流程
需求分析:
实现网站搭建的过程:首先进行网站的需求性分析
网站可分为前台系统和后台系统,由不同的功能拆分为不同的模块
如下是一个电商网站可以拆分出的模块:
在编写代码前,我们要先对网站进行架构,通过分层设计网站的不同组件,软件开发人员可以选择修改和添加应用层,而非全局作出更改
如下是经典的三层结构:
接入层:提供静态内容的web前端服务器和部分动态缓存内容。
逻辑层:生成动态内容的应用服务器。
存储层:提供数据存储的服务器
TIPS:
为什么之前在用Django的时候直接runserver就好了呢?因为Django的开发服务器(runserver)是一个轻量级服务器,能够处理HTTP请求和提供静态资源服务,但主要应用于调试阶段,由于单线程且没有负载均衡SSL加密等功能,在生产环境中我们需要专业的接入层,像是Nginx
模块引入:
为了确保功能的实现,我们可以引入所需的功能模块
其中,installed_app这个设置告诉用户在该项目中安装了哪些程序,可以是第三方或自定义的,也可以是django自带的
middleware这个设置定义了处理请求的中间件和响应件,中间件是处理请求和响应的钩子,可用于请求到达视图/响应返回客户段前执行特定的操作。
在构建网站的过程中,我们要把不同需求拆解为功能模块的同时为其添加数据库表结构
首先,我们来进行用户模块的构建:
INSTALLED_APPS = [# 其他已安装的应用...'django.contrib.auth', # 用户验证框架和模型'django.contrib.contenttypes', # 权限管理]MIDDLEWARE = [# 其他中间件...'django.contrib.sessions.middleware.SessionMiddleware', # 会话管理系统'django.contrib.auth.middleware.AuthenticationMiddleware', # 用户验证模型]
这是利用了Django自带的用户模块,配置当中的.就是/的意思,暗含代码路径在django/contrib/auth/moddles.py,模型里面包含这些内容
让我们先来了解一下用户模块:
django.contrib.auth 模块为我们提供了用户认证系统的核心功能,包括用户模型、表单、视图、URL 配置等,这些功能已经预先定义好,可以直接使用或根据需要进行扩展。它是一个完整的用户认证框架,旨在帮助开发者快速实现用户注册、登录、权限管理等功能,而无需从头开始编写这些代码。
Django 自带用户认证模块提供的功能
以下是 Django 自带用户认证模块(django.contrib.auth)为你预先定义好的内容:
----
1. 用户模型(User)
Django 提供了一个默认的用户模型 User,定义在 django.contrib.auth.models 中。它包含以下字段:
• username:用户名
• password:密码(加密存储)
• email:邮箱
• first_name 和 last_name:用户姓名
• is_active:是否激活
• is_staff:是否是管理员
• is_superuser:是否是超级用户
• groups 和 user_permissions:用户组和权限
你可以直接使用这个默认的用户模型,或者通过继承 AbstractUser 或 AbstractBaseUser 来扩展它。
----
2. 表单(forms)
Django 提供了一些内置的表单类,用于用户注册、登录、密码修改等功能:
• UserCreationForm:用户注册表单
• AuthenticationForm:用户登录表单
• PasswordChangeForm:密码修改表单
• SetPasswordForm:设置密码表单
• PasswordResetForm:密码重置表单
这些表单类已经预定义了字段和验证逻辑,你可以直接使用,也可以通过继承它们来自定义字段或验证规则。
----
3. 视图(views)
Django 提供了一些内置的视图函数,用于处理用户认证相关的操作:
• login:用户登录
• logout:用户登出
• password_change:密码修改
• password_reset:密码重置
• password_reset_done:密码重置完成
• password_reset_confirm:密码重置确认
• password_reset_complete:密码重置完成提示
这些视图函数可以直接在 URL 配置中使用,或者通过继承 View 类来自定义视图逻辑。
----
4. URL 配置(urls)
Django 提供了一个 auth 应用的 URL 配置模块 django.contrib.auth.urls,它包含了用户认证相关的 URL 路由,例如:
from django.contrib.auth import views as auth_viewsurlpatterns = [path('login/', auth_views.LoginView.as_view(), name='login'),path('logout/', auth_views.LogoutView.as_view(), name='logout'),path('password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'),path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),path('password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'),path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),]
你可以直接在项目的 urls.py 文件中包含这些 URL 路由,或者根据需要自定义 URL 路径和视图参数。
----
5. 中间件和会话管理
Django 的认证系统还提供了中间件(如 AuthenticationMiddleware)和会话管理功能,用于在请求中自动处理用户认证信息,并将用户对象绑定到 request.user。
----
扩展:
在很多时候我们都需要对Django自带的模型进行相应的拓展
关联表:
这个时候可以使用关联表
用如下的onetoonefield方法创建:
from django.db import modelsfrom django.contrib.auth.models import Userclass Profile(models.Model):GENDER_CHOICES = (('M', 'Male'), # 男性('F', 'Female'), # 女性)user = models.OneToOneField(User, on_delete=models.CASCADE)gender = models.CharField(max_length=1, choices=GENDER_CHOICES) # 性别birth_date = models.DateField(null=True, blank=True) # 出生日期
模型字段解释
1. GENDER_CHOICES:
• 这是一个元组列表,用于定义性别字段的选项。每个元组包含两个元素:第一个是存储在数据库中的值,第二个是显示给用户的值。
2. user:
• 这是一个 OneToOneField 字段,它建立了 Profile 模型和 User 模型之间的一对一关系。
• User 是 Django 内置的用户模型,通常包含用户名、密码、电子邮件等基本信息。
• on_delete=models.CASCADE 参数指定了当关联的 User 实例被删除时,相关的 Profile 实例也会被级联删除。
3. gender:
• 这是一个 CharField 字段,用于存储用户的性别。
• max_length=1 指定了性别字段的最大长度为1个字符。
• choices=GENDER_CHOICES 参数将性别字段的值限制为在 GENDER_CHOICES 中定义的选项。
4. birth_date:
• 这是一个 DateField 字段,用于存储用户的出生日期。
• null=True 允许该字段在数据库中存储为 NULL,这意味着它可以为空。
• blank=True 允许在 Django 管理后台或表单中不填写该字段。
关联表的使用
在 Django 中,当你使用 OneToOneField 时,Django 会在数据库中创建一个新的表来存储 Profile 模型的数据。这个表会包含一个额外的字段(通常是 user_id),这个字段是一个外键,指向 User 表的主键。
例如,如果你的 User 表的主键是 id,那么 Profile 表可能会包含以下字段:
• id:Profile 表的主键。
• user_id:外键,指向 User 表的 id 字段。
• gender:存储性别的字段。
• birth_date:存储出生日期的字段。
这种设计允许每个 User 实例都有一个对应的 Profile 实例,而每个 Profile 实例只能属于一个 User 实例。这种一对一的关系在数据库中通过外键约束来实现,确保了数据的一致性和完整性。
总结
这段代码通过 OneToOneField 创建了一个 Profile 模型,它与 User 模型建立了一对一的关系。这种关系通过在 Profile 表中添加一个外键字段来实现,该字段指向 User 表的主键。这种设计使得每个用户都有一个相关的个人资料,而每个个人资料只属于一个用户。
信号定义:
在创建用户过程中多次会用到创建用户的代码,为了避免重复创建,我们将定义一个信号,在创建用户时自动创建档案:
from django.apps import AppConfigclass MyAppConfig(AppConfig):name = 'myapp'def ready(self):import myapp.signals
该方法使用要在myapp下创建一个signals.py文件并且在app.py文件当中重写ready方法来连接信号,以及更新installed_apps
INSTALLED_APPS = [...'myapp.apps.MyAppConfig',...]
TIPS:当然,signals的内容也可以直接写在models里面
然后我们在更改完models之后再去更改视图和模版文件
模板:
<h2>{{ user.get_full_name }}</h2><ul><li>Username: {{ user.username }}</li> <!-- 显示用户名 --><li>Location: {{ user.profile.gender }}</li> <!-- 显示性别 --><li>Birth Date: {{ user.profile.birth_date }}</li> <!-- 显示出生日期 --></ul>
视图:
def update_profile(request, user_id):user = User.objects.get(pk=user_id) # 获取用户对象user.profile.gender = 'M' # 设置性别user.save() # 保存
视图函数当中反应的是对于用户档案的更新:在更新用户档案时,浏览器会先上传一个表单,然后由服务器来处理这个表单,处理的方法就是视图函数当中的先获取数据对象,调用先前定义的模型进行修改,然后再调用save方法进行更新
注意!!:这里储存的是模型的字段,因此不能直接储存到数据库,我们需要使用forms.ModelForm类创建表单
from django import formsclass UserForm(forms.ModelForm):class Meta:model = User # 关联User模型fields = ('first_name', 'last_name', 'email') # 表单字段class ProfileForm(forms.ModelForm):class Meta:model = Profile # 关联Profile模型fields = ('url', 'gender', 'birth_date') # 表单字段
然后再编写对应用户登陆的视图
from django.contrib import messagesfrom django.shortcuts import redirect, renderfrom django.db import transactionfrom .forms import UserForm, ProfileForm@login_required # 验证登录@transaction.atomicdef update_profile(request):if request.method == 'POST': # POST请求user_form = UserForm(request.POST, instance=request.user) # 获取用户表单信息profile_form = ProfileForm(request.POST, instance=request.user.profile) # 获取表单信息if user_form.is_valid() and profile_form.is_valid(): # 验证通过则保存信息user_form.save()profile_form.save()messages.success(request, _('Your profile was successfully updated!'))return redirect('settings:profile')else: # 验证不通过则显示错误信息messages.error(request, _('Please correct the error below.'))else: # 其他请求,一般是GET请求user_form = UserForm(instance=request.user)profile_form = ProfileForm(instance=request.user.profile)# 返回表单页面return render(request, 'profiles/profile.html', {'user_form': user_form,'profile_form': profile_form})
如上代码当中,用户如果用的是post方法,则获取表单信息与之对照,如果是get方式则返回表单页面,并将内容填入表单,(对应的,我们需要更改其模版文件)
<form method="post">{% csrf_token %}{{ user_form.as_p }} <!-- 渲染用户表单 -->{{ profile_form.as_p }} <!-- 渲染Profile表单 --><button type="submit">Save changes</button> <!-- 提交按钮 --></form>
继承:
如果我们的用户系统完全不需要某一字段,也可以使用继承的方式(AbstractBaseUser)
from __future__ import unicode_literalsfrom django.db import modelsfrom django.core.mail import send_mailfrom django.contrib.auth.models import PermissionsMixinfrom django.contrib.auth.base_user import AbstractBaseUserfrom django.utils.translation import ugettext_lazy as _from .managers import UserManagerclass User(AbstractBaseUser, PermissionsMixin):GENDER_CHOICES = (('M', 'Male'), # 男性('F', 'Female'), # 女性)gender = models.CharField(max_length=1, choices=GENDER_CHOICES) # 性别birth_date = models.DateField(null=True, blank=True) # 出生年月email = models.EmailField(_('email address'), unique=True) # 电子邮件first_name = models.CharField(_('first name'), max_length=30, blank=True)last_name = models.CharField(_('last name'), max_length=30, blank=True)date_joined = models.DateTimeField(_('date joined'), auto_now_add=True) # 注册时间is_active = models.BooleanField(_('active'), default=True) # 是否活跃avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) # 用户头像objects = UserManager()USERNAME_FIELD = 'email'REQUIRED_FIELDS = []class Meta:verbose_name = _('user')verbose_name_plural = _('users')def get_full_name(self): # 获取用户全名full_name = '%s %s' % (self.first_name, self.last_name)return full_name.strip()def get_short_name(self):return self.first_namedef email_user(self, subject, message, from_email=None, **kwargs): # 向用户发送电子邮件send_mail(subject, message, from_email, [self.email], **kwargs)
在使用继承AbstractBaseUser时,有很多相关的限制(建议直接重新自己写)
如果要添加某一些字段,可以采用继承AbstractUser方法,运营此法可对于原有的类进行更改
from django.db import modelsfrom django.contrib.auth.models import AbstractUserclass User(AbstractUser):GENDER_CHOICES = (('M', 'Male'), # 男性('F', 'Female'), # 女性)gender = models.CharField(max_length=1, choices=GENDER_CHOICES) # 性别birth_date = models.DateField(null=True, blank=True) # 出生年月
模块设计的大概步骤:
然后我们再来进行商品库模块的设计:
首先我们设计了类别模型、商品模型以及类别和商品的多对多的模型
from django.db import modelsclass Category(models.Model):name = models.CharField('Name', max_length=255, db_index=True) # 类别名称description = models.TextField('Description', blank=True) # 类别描述products = models.ManyToManyField('Product') # 多对多关系class Product(models.Model):title = models.CharField('Title') # 商品名称description = models.TextField('Description', blank=True) # 商品描述attributes = models.TextField('Attribute', blank=True) # 商品附属信息date_created = models.DateTimeField() # 商品创建时间
在上述代码中,可以把manytomany理解为一个声明,表示两个表要建联,而ProductCategory则可以视作声明的具体内容
from django.http import HttpResponsefrom .models import Product, Categorydef get_product_detail(request, product_id): # 获取商品详情return Product.objects.get(pk=product_id)def get_all_products(request, category_id): # 通过类别获取商品列表return Category.objects.get(pk=category_id).products.all()
定义相应的视图函数(根据搜索返回商品的过程,实际搜索当中要比这复杂的多因为用户的描述和实际商品的名称并非完全相同,此时也要给出最合理的结果)
{% for product in productions %}<p>{{ product.title }}</p> <!-- 商品的名称 --><p>{{ product.description }}</p> <!-- 商品的描述 -->{% endfor %}
并给出相应的模版文件(这里用了for标签来渲染列表)
总结:
总之,网站的制作就是先进行需求分析,根据需求分析得到各个功能模块,然后对每一个模块进行编写,编写的顺序为:模型文件再到视图函数及其对应的模版文件,urls.py和settings.py的两个视图函数的编写可以放在这一步之前也可以是之后,但是为了方便,编写settings.py之前我们最好还是要明确自己要用到的所有models和middleware
相关文章:

网站搭建基本流程
需求分析: 实现网站搭建的过程:首先进行网站的需求性分析 网站可分为前台系统和后台系统,由不同的功能拆分为不同的模块 如下是一个电商网站可以拆分出的模块: 在编写代码前,我们要先对网站进行架构,通过…...

mysql 存储空间增大解决方案
一:查询数据库中表占比比较多的表 SELECT table_name AS "Tables", round(((data_length index_length) / 1024 / 1024), 2) AS "Size (MB)" FROM information_schema.tables WHERE table_schema "自己的数据库名"; …...
深入解析队列与广度优先搜索(BFS)的算法思想:原理、实现与应用
目录 1. 队列的基本概念 2. 广度优先搜索(BFS)的基本概念 3. 队列在BFS中的作用 4. BFS的实现细节 5. C实现BFS 6. BFS的应用场景 7. 复杂度分析 8. 总结 1. 队列的基本概念 队列(Queue)是一种先进先出(FIFO, …...
Swap to Gather-----
C - 烟销日出不见人 问题陈述 给定一个长度为 NN 的字符串 SS,由 0 和 1 组成。保证 SS 至少包含一个 1。 您可以执行以下操作任意次数(可能为零): 选择一个整数 ii (1≤i≤N−11≤i≤N−1),并交换 SS 的第 ii 个和…...

使用DeepSeek+本地知识库,尝试从0到1搭建高度定制化工作流(自动化篇)
7.5. 配图生成 目的:由于小红书发布文章要求图文格式,因此在生成文案的基础上,我们还需要生成图文搭配文案进行发布。 原实现思路: 起初我打算使用deepseek的文生图模型Janus进行本地部署生成,参考博客:De…...
Python 函数式编程全攻略:从理论到实战的深度解析
本文深入剖析 Python 函数式编程,详细讲解其概念、核心特性(迭代器、生成器等)、内置函数及相关模块(itertools、functools ),结合丰富示例与直观图表,助力读者全面掌握函数式编程技巧ÿ…...

Ollama 在 LangChain 中的使用
文章目录 一、langChain 介绍二、环境安装1.依赖库安装2.下载模型 三、基本使用示例1.使用 ChatPromptTemplate 进行对话2.流式输出3.工具调用4.多模态模型调用 四、进阶使用1.使用 ConversationChain 进行对话2.自定义提示模板3.构建一个简单的 RAG 问答系统 五、遇到问题与解…...
使用apt-rdepends制作软件离线deb安装包
使用apt-rdepends制作软件离线deb安装包 除基础软件外,还要获取软件依赖包。 依赖包工具安装 apt-get install apt-rdependsapt-rdepends工具使用 使用apt-rdepends工具,递归方式分析软件依赖,下载软件包本体,和依赖包。制作时…...
根据POD名称生成 三部曲:get、describe、log、exec
#!/bin/bash# 定义颜色变量 RED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m NC\033[0m # No Color# 检查是否传入 Pod 名称作为参数 if [ -z "$1" ]; then# 如果没有传参,则提示用户输入 Pod 名称echo -e "${YELLOW}Please enter the Pod name:${…...

SQL sever数据导入导出实验
1.创建数据库TCP-H (1)右键“数据库”,点击“新建数据库”即可 (2)用sql语言创建,此处以创建数据库DB_test为例,代码如下: use master;go--检查在当前服务器系统中的所有数据里面…...

python环境的yolov11.rknn物体检测
1.首先是我手里生成的一个yolo11的.rknn模型: 2.比对一下yolov5的模型: 2.1 yolov5模型的后期处理: outputs rknn.inference(inputs[img2], data_format[nhwc])np.save(./onnx_yolov5_0.npy, outputs[0])np.save(./onnx_yolov5_1.npy, outpu…...
I2C、SPI、UART
I2C:串口通信,同步,半双工,双线(数据线SDA时钟线SCL),最大距离1米到几米 SPI(串行外设接口):串口通信,同步,全双工,四线&…...
如何监控和优化 MySQL 中的慢 SQL
如何监控和优化 MySQL 中的慢 SQL 前言一、什么是慢 SQL?二、如何监控慢 SQL?1. 启用慢查询日志启用方法:日志内容: 2. 使用 mysqldumpslow 分析日志 三、如何分析慢 SQL?1. 使用 EXPLAIN 分析执行计划使用方法&#x…...
13-二叉树最小深度-深度优先(DFS)
一、定义 什么是二叉树的最小深度? 二叉树的最小深度是指从根节点到最近的叶子节点的最短路径上的节点数。叶子节点是指没有子节点的节点。 举个例子: 1/ \2 3/ 4 这棵树的最小深度是 2,因为从根节点 1 到叶子节点 3 的路径最短&#x…...

51单片机入门_10_数码管动态显示(数字的使用;简单动态显示;指定值的数码管动态显示)
接上篇的数码管静态显示,以下是接上篇介绍到的动态显示的原理。 动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选ÿ…...

代码补全『三重奏』:EverEdit如何用上下文识别+语法感知+智能片段重构你的编码效率!
1 代码自动完成 1.1 应用场景 在编辑文档时,为了提高编辑效率,编辑器一般都会带有自动完成功能,比如:输入括号时自动补全另一半,输入文字时,自动补全剩下的部分。 1.2 使用方法 1.2.1 自动缩进 单击主菜…...

电脑系统损坏,备份文件
一、工具准备 1.U盘:8G以上就够用,注意会格式化U盘,提前备份U盘内容 2.电脑:下载Windows系统并进行启动盘制作 二、Windows启动盘制作 1.微软官网下载启动盘制作工具微软官网下载启动盘制作工具https://www.microsoft.com/zh-c…...

Token Statistics Transformer:线性注意力革命,重新定义Transformer效率天花板
“TOKEN STATISTICS TRANSFORMER: LINEAR-TIME ATTENTION VIA VARIATIONAL RATE REDUCTION” 由Ziyang Wu等人撰写。文章提出一种新型Transformer注意力算子,通过对最大编码率降低( M C R 2 MCR^{2} MCR2)目标的变分形式进行展开优化得到&…...
Django 5实用指南(二)项目结构与管理
2.1 Django5项目结构概述 当你创建一个新的 Django 项目时,Django 会自动生成一个默认的项目结构。这个结构是根据 Django 的最佳实践来设计的,以便开发者能够清晰地管理和维护项目中的各种组件。理解并管理好这些文件和目录结构是 Django 开发的基础。…...
JAVA监听器(学习自用)
一、什么是监听器 servlet监听器是一种特殊的接口,用于监听特定的事件(如请求创建和销毁、会话创建和销毁、上下文的初始化和销毁)。 当Web应用程序中反生特定事件时,Servlet容器就会自动调用监听器中相应的方法来处理这些事件。…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...

Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...