网站搭建基本流程

需求分析:

实现网站搭建的过程:首先进行网站的需求性分析

网站可分为前台系统和后台系统,由不同的功能拆分为不同的模块

如下是一个电商网站可以拆分出的模块:

在编写代码前,我们要先对网站进行架构,通过分层设计网站的不同组件,软件开发人员可以选择修改和添加应用层,而非全局作出更改

如下是经典的三层结构:

接入层:提供静态内容的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_views



urlpatterns = [

    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 models

from django.contrib.auth.models import User



class 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 AppConfig



class 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 forms



class 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 messages

from django.shortcuts import redirect, render

from django.db import transaction

from .forms import UserForm, ProfileForm



@login_required  # 验证登录

@transaction.atomic

def 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_literals

from django.db import models

from django.core.mail import send_mail

from django.contrib.auth.models import PermissionsMixin

from django.contrib.auth.base_user import AbstractBaseUser

from django.utils.translation import ugettext_lazy as _

from .managers import UserManager



class 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_name



    def email_user(self, subject, message, from_email=None, **kwargs):  # 向用户发送电子邮件

        send_mail(subject, message, from_email, [self.email], **kwargs)

在使用继承AbstractBaseUser时,有很多相关的限制(建议直接重新自己写)

如果要添加某一些字段,可以采用继承AbstractUser方法,运营此法可对于原有的类进行更改

from django.db import models

from django.contrib.auth.models import AbstractUser



class 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 models



class 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 HttpResponse

from .models import Product, Category



def 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

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

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

相关文章

反射机制的简单示例

一个使用反射机制的简单示例&#xff0c;这个示例将展示如何使用反射来实现一个通用的数据导出功能。 首先&#xff0c;让我们创建必要的项目结构和文件&#xff1a; 首先修改 pom.xml 添加依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?&…

Qt:多元素控件

目录 多元素控件介绍 QListWidget QTableWidget QTreeWidget 多元素控件介绍 多元素控件表示这个控件中包含了很多的元素&#xff0c;元素可能指的是字符串&#xff0c;也可以指的是更加复杂的数据结构、图片等等 Qt 中提供的多元素控件有: QListWidgetQListViewQTableW…

DeepSeek 助力 Vue 开发:打造丝滑的范围选择器(Range Picker)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

STL —— 洛谷字符串(string库)入门题(蓝桥杯题目训练)(一)

目录 一、B2109 统计数字字符个数 - 洛谷 算法代码&#xff1a; 1. 引入库和命名空间 2. 主函数 3. 读取输入 4. 变量初始化 5. 遍历字符串 6. 输出结果 7. 返回值 总结 评测记录&#xff1a; 二、B2110 找第一个只出现一次的字符 - 洛谷 方法一&#xff1a;算法代…

Golang GORM系列:GORM并发与连接池

GORM 是一个流行的 Go 语言 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;用于简化数据库操作。它支持连接池和并发访问功能&#xff0c;这些功能对于高性能、高并发的应用场景非常重要。本文结合示例详细介绍gorm的并发处理能力&#xff0c;以及如何是哟个连接池提升…

C#之上位机开发---------C#通信库及WPF的简单实践

〇、上位机&#xff0c;分层架构 界面层 要实现的功能&#xff1a; 展示数据 获取数据 发送数据 数据层 要实现的功能&#xff1a; 转换数据 打包数据 存取数据 通信层 要实现的功能&#xff1a; 打开连接 关闭连接 读取数据 写入数据 实体类 作用&#xff1a; 封装数据…

Ubuntu24安装MongoDB(解压版)

目录 0.需求说明1.环境检查2.下载软件2.1.下载MongoDB服务端2.2.下载MongoDB连接工具(可略过)2.3.检查上传或下载的安装包 3.安装MongoDB3.1.编辑系统服务3.2.启动服务3.3.客户端连接验证3.3.1.创建管理员用户 4.远程访问4.1.开启远程访问4.2.开放防火墙 0.需求说明 问&#x…

《DeepSeek-V3:人工智能大语言模型》

《DeepSeek-V3:人工智能大语言模型》 1. 引言 我们介绍了 DeepSeek-V3,这是一个强大的专家混合 (MoE) 语言模型,总共有 671B 个参数,每个令牌激活了 37B。 为了实现高效的推理和具有成本效益的训练,DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些…

解锁机器学习核心算法 | K -近邻算法:机器学习的神奇钥匙

一、引言 今天我们继续学习机器学习核心算法 —— K - 近邻&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09;算法。它就像是一位经验丰富的 “老江湖”&#xff0c;以其简单而又强大的方式&#xff0c;在众多机器学习任务中占据着不可或缺的地位。 K - 近邻…

算法分析—— 《归并排序》

《排序数组》 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题&#xff0c;时间复杂度为 O(nlog(n))&#xff0c;并且空间复杂度尽可能小。 示例 1&#xff1a; 输入&#xff1a;nums [5,2…

linux云服务器部署deepseek,并通过网页访问

参考视频&#xff1a;https://www.douyin.com/root/search/linux%E5%AE%89%E8%A3%85%20deepseek?aid3aa2527c-e4f2-4059-b724-ab81a140fa8b&modal_id7468518885570940214&typegeneral 修改ollama配置文件 vim /etc/systemd/system/ollama.service 我的电脑硬盘只有4…

FastAdmin后端列表导入表格数据

后台添加数据的时候增加通过表格导入功能 如下图index.html页面增加导入和模板下载按钮代码如下 <div class"panel panel-default panel-intro">{:build_heading()}<div class"panel-body"><div id"myTabContent" class"ta…

可调节图片参数,解决图片模糊及尺寸过小问题的工具

软件介绍 你是否正为图片模糊、尺寸太小而烦恼&#xff1f;别担心&#xff0c;有这样一款神器能帮你轻松解决。它能精准调节图片参数&#xff0c;即便原本模糊不清的图片&#xff0c;经它处理后也能变得高清锐利&#xff0c;瞬间让图片焕然一新。而且&#xff0c;它还具备导出…

Windows网络安全基础

随着互联网的发展和普及&#xff0c;Windows网络安全问题愈发严重。在本文中&#xff0c;我们将会介绍Windows网络安全的基本概念&#xff0c;包括网络攻击类型、网络安全威胁、网络安全防御措施等等&#xff0c;帮助初学者更好地了解Windows网络安全。 一、网络攻击类型 网络…

代码补全『三重奏』:EverEdit如何用上下文识别+语法感知+智能片段重构你的编码效率!

1 代码自动完成 1.1 应用场景 在编辑文档时&#xff0c;为了提高编辑效率&#xff0c;编辑器一般都会带有自动完成功能&#xff0c;比如&#xff1a;输入括号时自动补全另一半&#xff0c;输入文字时&#xff0c;自动补全剩下的部分。 1.2 使用方法 1.2.1 自动缩进 单击主菜…

vue,vue3 keepalive没有效果,无法缓存页面include无效,keep-alive

keepalive没有效果&#xff0c;无法缓存页面&#xff1f; 问题大概是组件的name值不对应&#xff0c;vue2修改组件文件的name值&#xff0c;vue3保持组件文件名称和路由页面配置的name一致就可以了&#xff0c;如果vue3不想保持一致&#xff0c;必须手动在文件后面添加export..…

栈回溯方案

注&#xff1a;栈回溯无法很好的定位到未调优化的函数&#xff0c;需要编译前使用 -fno-optimize-sibling-calls 选项禁止尾调优化。 基于unwind的栈回溯 在 arm 架构下&#xff0c;不少32位系统用的是 unwind 形式的栈回溯&#xff0c;这种栈回溯要复杂很多。首先需要程序有一…

【存储中间件API】MySQL、Redis、MongoDB、ES常见api操作及性能比较

常见中间件api操作及性能比较 ☝️ MySQL crud操作✌️ maven依赖✌️ 配置✌️ 定义实体类✌️ 常用api ☝️ Redis crud操作✌️ maven依赖✌️ 配置✌️ 常用api ☝️ MongoDB crud操作✌️ maven依赖✌️ 配置文件✌️ 定义实体类✌️ MongoDB常用api ☝️ ES crud操作 ⭐️…

解锁D3.js与PlantUML的交互奥秘:探索知识图谱数据可视化新领域

解锁D3.js与PlantUML的交互魔法&#xff1a;数据可视化新征程 在前端开发的广袤天地里&#xff0c;数据可视化一直是一颗璀璨的明珠&#xff0c;吸引着无数开发者探索其奥秘。而当D3.js这一强大的JavaScript库&#xff0c;遇上专注于创建UML图的PlantUML&#xff0c;一场奇妙的…

DeepSeek24小时写作机器人,持续创作高质量文案

内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求&#xff0c;人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容&#xff1f;DeepSeek写作机器人&#xff0c;一款24小时持续创作的智能工具&#xff0c;为企业和个人提…