当前位置: 首页 > news >正文

第20篇:Python 开发进阶:使用Django进行Web开发详解

第20篇:使用Django进行Web开发

内容简介

在上一篇文章中,我们深入探讨了Flask框架的高级功能,并通过构建一个博客系统展示了其实际应用。本篇文章将转向Django,另一个功能强大且广泛使用的Python Web框架。我们将介绍Django的核心概念,包括项目与应用结构、模型与数据库迁移、管理后台、模板与静态文件管理,以及如何将Django应用部署到生产环境。通过详细的代码示例和实战项目,您将掌握使用Django构建复杂且可扩展的Web应用的关键技能。


目录

  1. Django框架介绍
    • Django的历史与特点
    • Django的优势
    • 安装与设置
  2. 项目与应用结构
    • 创建Django项目
    • 理解项目与应用
    • 项目目录结构详解
  3. 模型与数据库迁移
    • 定义模型
    • 数据库配置
    • 执行迁移
    • 数据库操作
  4. 管理后台
    • 激活管理后台
    • 自定义管理界面
    • 权限与用户管理
  5. 模板与静态文件管理
    • Django模板引擎
    • 模板继承
    • 静态文件管理
    • 自定义模板标签与过滤器
  6. 部署Django应用
    • 选择部署平台
    • 使用Gunicorn和Nginx
    • 配置环境变量与安全设置
    • 启用HTTPS
  7. 示例项目:在线商店
    • 项目结构
    • 创建应用与定义模型
    • 实现用户认证
    • 产品管理与购物车功能
    • 订单处理与支付集成
  8. 常见问题及解决方法
    • 问题1:如何处理表单的CSRF保护?
    • 问题2:如何优化数据库查询性能?
    • 问题3:如何实现密码的安全存储?
    • 问题4:如何部署Django应用到生产环境?
  9. 总结

Django框架介绍

Django的历史与特点

Django是一个高级的Python Web框架,旨在快速开发和简化复杂、数据库驱动的网站的构建过程。由Adrian HolovatySimon Willison在2003年开发,并于2005年正式发布,Django以其“务实”而闻名,遵循“不要重复自己”(DRY)和“显式优于隐式”的设计原则。

主要特点

  • 快速开发:提供了大量内置功能,减少开发时间。
  • 可扩展性:适用于从简单的博客到复杂的企业级应用。
  • 安全性:内置多种安全保护机制,防范常见的Web攻击。
  • 完善的文档:拥有详尽的官方文档和活跃的社区支持。
  • 内置管理后台:自动生成的管理界面,方便数据管理。

Django的优势

  1. 全栈框架:Django涵盖了从前端到后端的各个方面,无需依赖大量第三方库。
  2. ORM(对象关系映射):简化数据库操作,支持多种数据库后端。
  3. 模板系统:强大的模板引擎,支持模板继承和自定义标签。
  4. 表单处理:自动生成表单,并提供丰富的表单验证功能。
  5. URL路由:灵活的URL配置,支持正则表达式和命名空间。
  6. 中间件:支持请求和响应处理的中间件,便于功能扩展。
  7. 社区与生态系统:拥有大量的第三方包和插件,满足各种需求。

安装与设置

安装Django

使用pip安装Django是最常见的方法。确保您已经安装了Python和pip

pip install Django

验证安装

安装完成后,可以通过以下命令验证Django是否成功安装:

django-admin --version

创建Django项目

创建项目

使用django-admin工具创建一个新的Django项目。

django-admin startproject mysite

运行开发服务器

进入项目目录并运行开发服务器。

cd mysite
python manage.py runserver

在浏览器中访问http://127.0.0.1:8000/,您将看到Django的欢迎页面,表明项目已成功创建并运行。


项目与应用结构

创建Django项目

Django项目是一个包含多个应用的集合,负责整体配置和协调。每个项目可以包含一个或多个应用,每个应用负责特定的功能模块。

django-admin startproject mysite
cd mysite

理解项目与应用

  • 项目(Project):整个Web应用的容器,包含全局配置、URL路由和应用的集合。
  • 应用(App):项目中的一个独立模块,负责特定功能,如用户管理、博客、商店等。

项目目录结构详解

创建项目后,您将看到以下目录结构:

mysite/
├── manage.py
├── mysite/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py

文件说明

  • manage.py:Django的命令行工具,用于执行各种任务,如运行开发服务器、数据库迁移等。
  • mysite/:项目的核心目录,包含全局配置文件。
    • init.py:将该目录标识为Python包。
    • settings.py:项目的配置文件,包含数据库配置、已安装的应用、静态文件配置等。
    • urls.py:全局URL路由配置,定义URL与视图的对应关系。
    • wsgi.py:WSGI兼容的Web服务器网关接口,用于部署。

创建应用

使用manage.py创建一个新的应用,例如创建一个名为blog的应用。

python manage.py startapp blog

更新项目配置

settings.py中添加新创建的应用到INSTALLED_APPS列表。

# mysite/settings.pyINSTALLED_APPS = [...'blog',
]

项目目录结构扩展

创建应用后,项目目录结构如下:

mysite/
├── manage.py
├── mysite/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── blog/├── __init__.py├── admin.py├── apps.py├── migrations/│   └── __init__.py├── models.py├── tests.py└── views.py

文件说明

  • admin.py:用于注册模型到Django管理后台。
  • apps.py:应用的配置文件。
  • migrations/:数据库迁移文件夹,用于记录模型的变化。
  • models.py:定义应用的数据模型。
  • tests.py:编写测试用例。
  • views.py:定义视图函数或类视图,处理请求和返回响应。

模型与数据库迁移

定义模型

Django的**模型(Models)**是用Python类定义的,代表数据库中的数据结构。每个模型类继承自django.db.models.Model

示例模型

blog/models.py中定义一个简单的博客文章模型。

# blog/models.py
from django.db import models
from django.contrib.auth.models import Userclass Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()date_posted = models.DateTimeField(auto_now_add=True)author = models.ForeignKey(User, on_delete=models.CASCADE)def __str__(self):return self.title

字段说明

  • title:文章标题,字符型,最大长度200。
  • content:文章内容,文本型。
  • date_posted:文章发布时间,自动设置为创建时的时间。
  • author:文章作者,外键关联到Django内置的用户模型。

数据库配置

默认情况下,Django使用SQLite作为数据库。可以在settings.py中更改数据库配置,以使用其他数据库如PostgreSQL、MySQL等。

示例:配置PostgreSQL

# mysite/settings.pyDATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': 'mydatabase','USER': 'mydatabaseuser','PASSWORD': 'mypassword','HOST': 'localhost','PORT': '5432',}
}

安装相应的数据库驱动

对于PostgreSQL,需要安装psycopg2

pip install psycopg2

执行迁移

定义模型后,需要创建数据库表。这通过Django的迁移系统完成。

  1. 创建迁移文件

    python manage.py makemigrations
    

    该命令会根据模型的变化生成迁移文件,记录数据库结构的变化。

  2. 应用迁移

    python manage.py migrate
    

    该命令会将迁移应用到数据库,创建或修改相应的表。

数据库操作

Django提供了强大的ORM(对象关系映射)工具,简化了数据库操作。

创建新记录

# 在Django shell中操作
python manage.py shell
from blog.models import Post
from django.contrib.auth.models import User# 获取用户
user = User.objects.get(username='john')# 创建新文章
post = Post(title='我的第一篇博客', content='这是博客内容。', author=user)
post.save()

查询数据

# 获取所有文章
posts = Post.objects.all()# 过滤查询
john_posts = Post.objects.filter(author__username='john')# 获取单个对象
post = Post.objects.get(id=1)

更新数据

post = Post.objects.get(id=1)
post.title = '更新后的标题'
post.save()

删除数据

post = Post.objects.get(id=1)
post.delete()

管理后台

激活管理后台

Django自带一个功能强大的管理后台,用于管理数据库中的数据。要激活管理后台,需要进行以下步骤。

  1. 创建超级用户

    python manage.py createsuperuser
    

    按提示输入用户名、电子邮件和密码,创建一个超级用户。

  2. 注册模型到管理后台

    blog/admin.py中注册模型。

    # blog/admin.py
    from django.contrib import admin
    from .models import Postadmin.site.register(Post)
    
  3. 运行开发服务器并访问管理后台

    python manage.py runserver
    

    在浏览器中访问http://127.0.0.1:8000/admin/,使用超级用户的凭据登录。您将看到已注册的Post模型,可以在管理后台中添加、编辑和删除文章。

自定义管理界面

可以自定义管理界面以更好地展示和管理数据。

示例:自定义Post模型的管理界面

# blog/admin.py
from django.contrib import admin
from .models import Postclass PostAdmin(admin.ModelAdmin):list_display = ('title', 'author', 'date_posted')search_fields = ('title', 'content')list_filter = ('date_posted', 'author')admin.site.register(Post, PostAdmin)

功能说明

  • list_display:在列表视图中显示的字段。
  • search_fields:启用搜索功能的字段。
  • list_filter:侧边栏的过滤选项。

权限与用户管理

Django的管理后台不仅用于数据管理,还支持权限和用户管理。

用户和组管理

在管理后台,可以创建和管理用户和组,分配不同的权限。

  1. 创建用户:在管理后台的“Users”部分创建新用户。
  2. 分配权限:为用户分配特定的权限,如添加、修改或删除某些模型。
  3. 创建组:将权限分配给组,然后将用户添加到组,简化权限管理。

示例:限制用户只能管理自己的文章

通过自定义ModelAdmin类,可以限制用户只能看到和管理自己的数据。

# blog/admin.py
from django.contrib import admin
from .models import Postclass PostAdmin(admin.ModelAdmin):list_display = ('title', 'author', 'date_posted')search_fields = ('title', 'content')list_filter = ('date_posted', 'author')def get_queryset(self, request):qs = super().get_queryset(request)if request.user.is_superuser:return qsreturn qs.filter(author=request.user)def save_model(self, request, obj, form, change):if not obj.pk:obj.author = request.userobj.save()admin.site.register(Post, PostAdmin)

功能说明

  • get_queryset:限制查询集,普通用户只能看到自己的文章。
  • save_model:在保存新文章时,自动将当前用户设置为作者。

模板与静态文件管理

Django模板引擎

Django使用自己的模板引擎,允许在HTML中嵌入动态内容。模板引擎支持变量、标签和过滤器,帮助生成动态页面。

基本模板示例

创建一个简单的模板blog/templates/blog/home.html

<!-- blog/templates/blog/home.html -->
<!DOCTYPE html>
<html>
<head><title>博客首页</title>
</head>
<body><h1>欢迎来到我的博客</h1><ul>{% for post in posts %}<li><a href="{% url 'blog:post_detail' post.id %}">{{ post.title }}</a> by {{ post.author.username }}</li>{% empty %}<li>暂无文章。</li>{% endfor %}</ul>
</body>
</html>

模板继承

模板继承允许定义一个基础模板,并在此基础上创建子模板,避免重复代码。

创建基础模板

创建templates/base.html

<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head><title>{% block title %}我的网站{% endblock %}</title><link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body><header><h1>我的网站</h1><nav><a href="{% url 'blog:home' %}">首页</a> |<a href="{% url 'admin:index' %}">管理后台</a></nav></header><main>{% block content %}{% endblock %}</main><footer><p>&copy; 2025 我的公司</p></footer>
</body>
</html>

创建子模板

修改blog/templates/blog/home.html,继承自base.html

<!-- blog/templates/blog/home.html -->
{% extends 'base.html' %}{% block title %}博客首页{% endblock %}{% block content %}<h2>博客文章</h2><ul>{% for post in posts %}<li><a href="{% url 'blog:post_detail' post.id %}">{{ post.title }}</a> by {{ post.author.username }}</li>{% empty %}<li>暂无文章。</li>{% endfor %}</ul>
{% endblock %}

静态文件管理

Django管理静态文件(如CSS、JavaScript、图片)通过STATICFILES系统处理。需要在settings.py中配置静态文件相关设置。

配置静态文件

# mysite/settings.pySTATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]

使用静态文件

在模板中加载静态文件。

{% load static %}<!DOCTYPE html>
<html>
<head><title>使用静态文件</title><link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body><!-- 页面内容 -->
</body>
</html>

收集静态文件

在生产环境中,使用collectstatic命令将所有静态文件收集到一个目录。

python manage.py collectstatic

自定义模板标签与过滤器

可以创建自定义的模板标签和过滤器,扩展模板引擎的功能。

创建自定义过滤器

  1. 创建模板标签目录

    在应用目录下创建templatetags文件夹,并添加__init__.py

    blog/
    ├── templatetags/
    │   ├── __init__.py
    │   └── blog_extras.py
    
  2. 定义过滤器

    # blog/templatetags/blog_extras.py
    from django import templateregister = template.Library()@register.filter(name='truncate')
    def truncate(value, arg):"""Truncate the string after a certain number of characters."""try:length = int(arg)except ValueError:return valueif len(value) > length:return value[:length] + '...'return value
    
  3. 使用过滤器

    在模板中加载并使用自定义过滤器。

    {% load blog_extras %}<p>{{ post.content|truncate:100 }}</p>
    

创建自定义标签

类似于过滤器,可以创建自定义标签以实现复杂的逻辑。

# blog/templatetags/blog_extras.py
from django import templateregister = template.Library()@register.simple_tag
def current_time(format_string):from django.utils import timezonereturn timezone.now().strftime(format_string)

使用自定义标签

{% load blog_extras %}<p>当前时间:{% current_time "%Y-%m-%d %H:%M" %}</p>

部署Django应用

选择部署平台

部署Django应用时,可以选择多种平台,包括:

  • 虚拟私有服务器(VPS):如DigitalOcean、Linode、AWS EC2。
  • 平台即服务(PaaS):如Heroku、PythonAnywhere、Google App Engine。
  • 容器化平台:如Docker、Kubernetes。

使用Gunicorn和Nginx

Gunicorn是一个Python WSGI HTTP服务器,适用于部署Django应用。Nginx作为反向代理服务器,处理客户端请求并转发给Gunicorn。

步骤

  1. 安装Gunicorn

    pip install gunicorn
    
  2. 运行Gunicorn

    在项目根目录下运行Gunicorn。

    gunicorn mysite.wsgi:application
    
  3. 配置Nginx

    创建一个Nginx配置文件,配置反向代理。

    # /etc/nginx/sites-available/mysiteserver {listen 80;server_name your_domain.com;location = /favicon.ico { access_log off; log_not_found off; }location /static/ {root /path/to/your/mysite;}location / {proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_pass http://127.0.0.1:8000;}
    }
    

    启用配置并重启Nginx。

    sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled
    sudo nginx -t
    sudo systemctl restart nginx
    
  4. 运行Gunicorn作为后台服务

    使用systemd创建一个服务文件。

    # /etc/systemd/system/gunicorn.service[Unit]
    Description=gunicorn daemon for Django project
    After=network.target[Service]
    User=youruser
    Group=www-data
    WorkingDirectory=/path/to/your/mysite
    ExecStart=/path/to/your/venv/bin/gunicorn mysite.wsgi:application --bind 127.0.0.1:8000[Install]
    WantedBy=multi-user.target
    

    启动并启用Gunicorn服务。

    sudo systemctl start gunicorn
    sudo systemctl enable gunicorn
    

配置环境变量与安全设置

配置环境变量

不要在代码中硬编码敏感信息。使用环境变量管理配置。

  1. 安装python-decouple

    pip install python-decouple
    
  2. 修改settings.py

    # mysite/settings.py
    from decouple import configSECRET_KEY = config('SECRET_KEY')
    DEBUG = config('DEBUG', default=False, cast=bool)DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': config('DB_NAME'),'USER': config('DB_USER'),'PASSWORD': config('DB_PASSWORD'),'HOST': config('DB_HOST'),'PORT': config('DB_PORT', default='5432'),}
    }
    
  3. 创建.env文件

    # .env
    SECRET_KEY=your_production_secret_key
    DEBUG=False
    DB_NAME=your_db_name
    DB_USER=your_db_user
    DB_PASSWORD=your_db_password
    DB_HOST=localhost
    DB_PORT=5432
    

    注意:确保.env文件不被版本控制系统(如Git)跟踪。

安全设置

  1. 禁用调试模式

    在生产环境中,确保DEBUG=False

  2. 设置允许的主机

    settings.py中配置ALLOWED_HOSTS

    ALLOWED_HOSTS = ['your_domain.com', 'www.your_domain.com']
    
  3. 使用HTTPS

    配置SSL证书,启用HTTPS,确保数据传输安全。

  4. 配置安全中间件

    确保以下中间件在MIDDLEWARE中启用,以增强安全性。

    MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','whitenoise.middleware.WhiteNoiseMiddleware',  # 用于静态文件管理...
    ]
    

启用HTTPS

使用Let’s Encrypt获取免费的SSL证书,并配置Nginx以启用HTTPS。

  1. 安装Certbot

    sudo apt-get update
    sudo apt-get install certbot python3-certbot-nginx
    
  2. 获取证书

    sudo certbot --nginx -d your_domain.com -d www.your_domain.com
    
  3. 自动续期

    Certbot自动配置证书续期。可以手动测试续期。

    sudo certbot renew --dry-run
    

更新Nginx配置

Certbot会自动修改Nginx配置以启用HTTPS。确保配置正确,并重启Nginx。

sudo systemctl restart nginx

示例项目:在线商店

为了综合应用上述知识,本节将带您构建一个功能完善的在线商店,包含用户注册与登录、产品管理、购物车功能及订单处理。

项目结构

online_store/
├── manage.py
├── online_store/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── store/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations/
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── templates/
│   ├── base.html
│   ├── store/
│   │   ├── home.html
│   │   ├── product_detail.html
│   │   └── cart.html
└── static/└── css/└── styles.css

创建应用与定义模型

创建应用

python manage.py startapp store

定义模型

store/models.py中定义ProductOrder模型。

# store/models.py
from django.db import models
from django.contrib.auth.models import Userclass Product(models.Model):name = models.CharField(max_length=200)description = models.TextField()price = models.DecimalField(max_digits=10, decimal_places=2)stock = models.PositiveIntegerField()image = models.ImageField(upload_to='product_images/', blank=True, null=True)def __str__(self):return self.nameclass Order(models.Model):user = models.ForeignKey(User, on_delete=models.CASCADE)ordered_date = models.DateTimeField(auto_now_add=True)is_completed = models.BooleanField(default=False)def __str__(self):return f'Order {self.id} by {self.user.username}'class OrderItem(models.Model):order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)product = models.ForeignKey(Product, on_delete=models.CASCADE)quantity = models.PositiveIntegerField(default=1)def __str__(self):return f'{self.quantity} of {self.product.name}'

执行迁移

python manage.py makemigrations
python manage.py migrate

实现用户认证

Django内置了用户认证系统,可以利用其功能实现用户注册与登录。

创建注册表单

store/forms.py中定义用户注册表单。

# store/forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationFormclass UserRegisterForm(UserCreationForm):email = forms.EmailField(required=True)class Meta:model = Userfields = ['username', 'email', 'password1', 'password2']

创建视图

store/views.py中添加注册和登录视图。

# store/views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from .forms import UserRegisterForm
from django.contrib.auth.forms import AuthenticationFormdef register(request):if request.method == 'POST':form = UserRegisterForm(request.POST)if form.is_valid():user = form.save()messages.success(request, f'账户 {user.username} 创建成功!请登录。')return redirect('login')else:form = UserRegisterForm()return render(request, 'store/register.html', {'form': form})def user_login(request):if request.method == 'POST':form = AuthenticationForm(request, data=request.POST)if form.is_valid():username = form.cleaned_data.get('username')password = form.cleaned_data.get('password')user = authenticate(username=username, password=password)if user is not None:login(request, user)messages.info(request, f'您已登录为 {username}.')return redirect('home')else:messages.error(request, '无效的用户名或密码。')else:messages.error(request, '无效的用户名或密码。')else:form = AuthenticationForm()return render(request, 'store/login.html', {'form': form})def user_logout(request):logout(request)messages.info(request, '您已成功注销。')return redirect('home')

配置URL

store/urls.py中定义应用的URL。

# store/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('register/', views.register, name='register'),path('login/', views.user_login, name='login'),path('logout/', views.user_logout, name='logout'),
]

在项目的主URL配置中包含应用的URL。

# online_store/urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include('store.urls')),
]

创建模板

创建store/templates/store/register.htmlstore/templates/store/login.html

<!-- store/templates/store/register.html -->
{% extends 'base.html' %}
{% load static %}{% block title %}注册{% endblock %}{% block content %}<h2>注册</h2><form method="POST">{% csrf_token %}{{ form.as_p }}<button type="submit">注册</button></form>
{% endblock %}
<!-- store/templates/store/login.html -->
{% extends 'base.html' %}
{% load static %}{% block title %}登录{% endblock %}{% block content %}<h2>登录</h2><form method="POST">{% csrf_token %}{{ form.as_p }}<button type="submit">登录</button></form>
{% endblock %}

更新基础模板

templates/base.html中添加导航链接。

<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head><title>{% block title %}在线商店{% endblock %}</title><link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body><header><h1>在线商店</h1><nav><a href="{% url 'home' %}">首页</a> |{% if user.is_authenticated %}<a href="{% url 'logout' %}">注销</a>{% else %}<a href="{% url 'login' %}">登录</a> |<a href="{% url 'register' %}">注册</a>{% endif %}</nav></header><main>{% if messages %}<ul>{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>{% endif %}{% block content %}{% endblock %}</main><footer><p>&copy; 2025 在线商店</p></footer>
</body>
</html>

产品管理与购物车功能

定义视图

store/views.py中添加首页和产品详情视图。

# store/views.py
from django.shortcuts import render, get_object_or_404
from .models import Productdef home(request):products = Product.objects.all()return render(request, 'store/home.html', {'products': products})def product_detail(request, pk):product = get_object_or_404(Product, pk=pk)return render(request, 'store/product_detail.html', {'product': product})

更新URL

# store/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('', views.home, name='home'),path('product/<int:pk>/', views.product_detail, name='product_detail'),path('register/', views.register, name='register'),path('login/', views.user_login, name='login'),path('logout/', views.user_logout, name='logout'),
]

创建模板

<!-- store/templates/store/home.html -->
{% extends 'base.html' %}
{% load static %}{% block title %}首页{% endblock %}{% block content %}<h2>产品列表</h2><ul>{% for product in products %}<li><a href="{% url 'product_detail' product.pk %}">{{ product.name }}</a> - ${{ product.price }}</li>{% empty %}<li>暂无产品。</li>{% endfor %}</ul>
{% endblock %}
<!-- store/templates/store/product_detail.html -->
{% extends 'base.html' %}
{% load static %}{% block title %}{{ product.name }}{% endblock %}{% block content %}<h2>{{ product.name }}</h2><p>{{ product.description }}</p><p>价格:${{ product.price }}</p><p>库存:{{ product.stock }}</p>{% if user.is_authenticated %}<form method="POST" action="{% url 'add_to_cart' product.pk %}">{% csrf_token %}<button type="submit">加入购物车</button></form>{% else %}<p><a href="{% url 'login' %}">登录</a>后可添加到购物车。</p>{% endif %}
{% endblock %}

实现购物车功能

购物车可以通过会话(Session)管理。

添加购物车视图

# store/views.py
from django.shortcuts import redirectdef add_to_cart(request, pk):product = get_object_or_404(Product, pk=pk)cart = request.session.get('cart', {})if str(pk) in cart:cart[str(pk)] += 1else:cart[str(pk)] = 1request.session['cart'] = cartmessages.success(request, f'已将 {product.name} 添加到购物车。')return redirect('home')def view_cart(request):cart = request.session.get('cart', {})cart_items = []total = 0for pk, quantity in cart.items():product = get_object_or_404(Product, pk=pk)total += product.price * quantitycart_items.append({'product': product,'quantity': quantity,'total_price': product.price * quantity})return render(request, 'store/cart.html', {'cart_items': cart_items, 'total': total})

更新URL

# store/urls.py
urlpatterns = [path('', views.home, name='home'),path('product/<int:pk>/', views.product_detail, name='product_detail'),path('add_to_cart/<int:pk>/', views.add_to_cart, name='add_to_cart'),path('cart/', views.view_cart, name='cart'),path('register/', views.register, name='register'),path('login/', views.user_login, name='login'),path('logout/', views.user_logout, name='logout'),
]

创建购物车模板

<!-- store/templates/store/cart.html -->
{% extends 'base.html' %}
{% load static %}{% block title %}购物车{% endblock %}{% block content %}<h2>购物车</h2>{% if cart_items %}<ul>{% for item in cart_items %}<li>{{ item.product.name }} - ${{ item.product.price }} x {{ item.quantity }} = ${{ item.total_price }}</li>{% endfor %}</ul><p>总计:${{ total }}</p><a href="{% url 'checkout' %}">结账</a>{% else %}<p>购物车为空。</p>{% endif %}
{% endblock %}

订单处理与支付集成

定义订单视图

store/views.py中添加结账视图。

# store/views.py
from django.contrib.auth.decorators import login_required@login_required
def checkout(request):cart = request.session.get('cart', {})if not cart:messages.error(request, '购物车为空。')return redirect('home')order = Order.objects.create(user=request.user)for pk, quantity in cart.items():product = get_object_or_404(Product, pk=pk)if product.stock < quantity:messages.error(request, f'产品 {product.name} 库存不足。')return redirect('cart')OrderItem.objects.create(order=order, product=product, quantity=quantity)product.stock -= quantityproduct.save()# 清空购物车request.session['cart'] = {}messages.success(request, '订单已创建成功!')return redirect('home')

更新URL

# store/urls.py
urlpatterns = [path('', views.home, name='home'),path('product/<int:pk>/', views.product_detail, name='product_detail'),path('add_to_cart/<int:pk>/', views.add_to_cart, name='add_to_cart'),path('cart/', views.view_cart, name='cart'),path('checkout/', views.checkout, name='checkout'),path('register/', views.register, name='register'),path('login/', views.user_login, name='login'),path('logout/', views.user_logout, name='logout'),
]

集成支付网关

可以集成第三方支付网关(如Stripe、PayPal)处理支付。以下是集成Stripe的简要示例。

  1. 安装Stripe库

    pip install stripe
    
  2. 配置Stripe

    settings.py中添加Stripe的API密钥。

    # mysite/settings.py
    STRIPE_PUBLIC_KEY = config('STRIPE_PUBLIC_KEY')
    STRIPE_SECRET_KEY = config('STRIPE_SECRET_KEY')
    
  3. 创建支付视图

    # store/views.py
    import stripe
    from django.conf import settingsstripe.api_key = settings.STRIPE_SECRET_KEY@login_required
    def payment(request):if request.method == 'POST':token = request.POST.get('stripeToken')try:charge = stripe.Charge.create(amount=int(request.POST['amount']) * 100,  # 转换为分currency='usd',description='在线商店订单',source=token,)messages.success(request, '支付成功!')return redirect('home')except stripe.error.CardError as e:messages.error(request, '支付失败:{}'.format(e))return render(request, 'store/payment.html', {'stripe_public_key': settings.STRIPE_PUBLIC_KEY})
    
  4. 更新URL

    # store/urls.py
    urlpatterns = [...path('payment/', views.payment, name='payment'),
    ]
    
  5. 创建支付模板

    <!-- store/templates/store/payment.html -->
    {% extends 'base.html' %}
    {% load static %}{% block title %}支付{% endblock %}{% block content %}<h2>支付</h2><form action="{% url 'payment' %}" method="POST">{% csrf_token %}<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"data-key="{{ stripe_public_key }}"data-amount="5000"data-name="在线商店"data-description="订单支付"data-currency="usd"data-email="{{ user.email }}"></script></form>
    {% endblock %}
    

注意:此示例仅为基本集成,实际应用中需要处理更复杂的支付流程和安全性措施。


常见问题及解决方法

问题1:如何处理表单的CSRF保护?

原因:跨站请求伪造(CSRF)是一种常见的Web攻击,Django通过生成和验证CSRF令牌来防止此类攻击。

解决方法

  1. 启用CSRF保护

    Django默认启用了CSRF中间件。确保MIDDLEWARE中包含'django.middleware.csrf.CsrfViewMiddleware'

    # mysite/settings.py
    MIDDLEWARE = [...'django.middleware.csrf.CsrfViewMiddleware',...
    ]
    
  2. 在表单中包含CSRF令牌

    在模板中的表单标签内添加{% csrf_token %}

    <form method="POST" action="{% url 'some_view' %}">{% csrf_token %}<!-- 表单字段 -->
    </form>
    
  3. 处理Ajax请求的CSRF

    对于Ajax请求,需要在请求头中包含CSRF令牌。可以在JavaScript中通过Cookie获取CSRF令牌并设置请求头。

    function getCookie(name) {let cookieValue = null;if (document.cookie && document.cookie !== '') {const cookies = document.cookie.split(';');for (let i = 0; i < cookies.length; i++) {const cookie = cookies[i].trim();// Does this cookie string begin with the name we want?if (cookie.substring(0, name.length + 1) === (name + '=')) {cookieValue = decodeURIComponent(cookie.substring(name.length + 1));break;}}}return cookieValue;
    }
    const csrftoken = getCookie('csrftoken');fetch('/some_url/', {method: 'POST',headers: {'X-CSRFToken': csrftoken,'Content-Type': 'application/json'},body: JSON.stringify({ /* 数据 */ })
    });
    

问题2:如何优化数据库查询性能?

原因:在处理大量数据时,未优化的查询可能导致性能瓶颈,影响应用响应速度。

解决方法

  1. 使用select_relatedprefetch_related

    这些方法可以减少数据库查询次数,优化关联对象的获取。

    # 使用select_related获取关联的外键对象
    posts = Post.objects.select_related('author').all()# 使用prefetch_related获取多对多或反向外键对象
    orders = Order.objects.prefetch_related('items__product').all()
    
  2. 添加数据库索引

    为频繁查询的字段添加索引,提高查询速度。

    # store/models.py
    class Product(models.Model):name = models.CharField(max_length=200, db_index=True)# 其他字段
    
  3. 分页查询

    对大量数据进行分页展示,减少单次查询的数据量。

    from django.core.paginator import Paginatordef home(request):products_list = Product.objects.all()paginator = Paginator(products_list, 10)  # 每页10个page_number = request.GET.get('page')page_obj = paginator.get_page(page_number)return render(request, 'store/home.html', {'page_obj': page_obj})
    

    在模板中显示分页链接:

    <!-- store/templates/store/home.html -->
    <ul>{% for product in page_obj %}<li>{{ product.name }} - ${{ product.price }}</li>{% endfor %}
    </ul><div class="pagination"><span class="page-links">{% if page_obj.has_previous %}<a href="?page=1">&laquo; 第一页</a><a href="?page={{ page_obj.previous_page_number }}">上一页</a>{% endif %}<span class="current">第 {{ page_obj.number }} 页,共 {{ page_obj.paginator.num_pages }} 页</span>{% if page_obj.has_next %}<a href="?page={{ page_obj.next_page_number }}">下一页</a><a href="?page={{ page_obj.paginator.num_pages }}">最后一页 &raquo;</a>{% endif %}</span>
    </div>
    
  4. 使用缓存

    利用Django的缓存框架缓存频繁访问的数据,减少数据库查询次数。

    from django.core.cache import cachedef home(request):products = cache.get('all_products')if not products:products = Product.objects.all()cache.set('all_products', products, 300)  # 缓存5分钟return render(request, 'store/home.html', {'products': products})
    
  5. 优化查询集

    仅获取需要的字段,减少数据传输量。

    products = Product.objects.only('name', 'price')
    
  6. 使用原生SQL查询

    在复杂查询场景下,使用原生SQL语句可能比ORM查询更高效。

    from django.db import connectiondef get_custom_data():with connection.cursor() as cursor:cursor.execute("SELECT name, price FROM store_product WHERE stock > %s", [10])row = cursor.fetchall()return row
    

问题3:如何实现密码的安全存储?

原因:用户密码的安全存储对于保护用户隐私和防止数据泄露至关重要。

解决方法

  1. 使用Django内置的用户模型

    Django的User模型已经实现了密码的哈希存储,确保密码的安全性。

    from django.contrib.auth.models import Useruser = User.objects.create_user(username='john', email='john@example.com', password='password123')
    
  2. 密码哈希算法

    Django使用强大的哈希算法(如PBKDF2)和盐(Salt)自动处理密码的加密和存储。

    # 验证密码
    user = User.objects.get(username='john')
    user.check_password('password123')  # 返回True或False
    
  3. 自定义用户模型(可选):

    如果需要扩展用户模型,可以创建自定义的用户模型,并确保继承自AbstractBaseUserPermissionsMixin,以保持安全性。

    # accounts/models.py
    from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
    from django.db import modelsclass CustomUser(AbstractBaseUser, PermissionsMixin):email = models.EmailField(unique=True)# 其他字段USERNAME_FIELD = 'email'REQUIRED_FIELDS = []
    

    注意:在创建自定义用户模型时,应尽早进行,以避免迁移和兼容性问题。

  4. 定期更新密码哈希算法

    随着技术的发展,Django会定期更新默认的密码哈希算法。可以通过PASSWORD_HASHERS设置自定义哈希器。

    # mysite/settings.py
    PASSWORD_HASHERS = ['django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    ]
    
  5. 强密码策略

    通过配置密码验证器,强制用户设置强密码。

    # mysite/settings.py
    AUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator','OPTIONS': {'min_length': 8,}},{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
    ]
    

问题4:如何部署Django应用到生产环境?

原因:开发环境与生产环境存在差异,直接在生产环境中运行Django开发服务器不安全且不高效。

解决方法

  1. 使用WSGI服务器

    部署Django应用时,应使用专业的WSGI服务器,如Gunicorn或uWSGI。

    # 使用Gunicorn
    pip install gunicorn
    gunicorn online_store.wsgi:application
    
  2. 配置反向代理

    使用Nginx或Apache作为反向代理服务器,处理客户端请求并转发给WSGI服务器。

    Nginx示例配置

    server {listen 80;server_name your_domain.com;location / {proxy_pass http://127.0.0.1:8000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}location /static/ {alias /path/to/your/online_store/static/;}location /media/ {alias /path/to/your/online_store/media/;}
    }
    
  3. 启用HTTPS

    使用SSL证书为您的网站启用HTTPS,提高数据传输的安全性。可以使用Let’s Encrypt免费获取SSL证书。

  4. 配置环境变量

    不要将敏感信息(如SECRET_KEY、数据库URI)硬编码在代码中,而应通过环境变量配置。

    export DJANGO_SECRET_KEY='your_production_secret_key'
    export DJANGO_DEBUG=False
    export DB_NAME='your_db_name'
    export DB_USER='your_db_user'
    export DB_PASSWORD='your_db_password'
    export DB_HOST='your_db_host'
    export DB_PORT='your_db_port'
    

    并在settings.py中使用这些变量。

  5. 日志管理

    配置日志记录,监控应用的运行状态和错误信息。

    # mysite/settings.py
    LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'file': {'level': 'DEBUG','class': 'logging.FileHandler','filename': '/path/to/your/logs/debug.log',},},'loggers': {'django': {'handlers': ['file'],'level': 'DEBUG','propagate': True,},},
    }
    
  6. 使用容器化

    使用Docker等容器技术,简化部署过程,提高环境一致性。

    Dockerfile示例

    FROM python:3.9-slimENV PYTHONUNBUFFERED 1WORKDIR /appCOPY requirements.txt /app/
    RUN pip install --no-cache-dir -r requirements.txtCOPY . /app/CMD ["gunicorn", "online_store.wsgi:application", "--bind", "0.0.0.0:8000"]
    

    构建与运行容器

    docker build -t online_store .
    docker run -d -p 8000:8000 online_store
    
  7. 定期备份

    定期备份数据库和重要数据,确保数据安全。

  8. 监控与维护

    使用监控工具(如Prometheus、Grafana)监控应用性能,及时发现并解决问题。


总结

在本篇文章中,我们深入探讨了Django框架的核心概念和高级功能,包括项目与应用结构、模型与数据库迁移、管理后台、模板与静态文件管理,以及如何将Django应用部署到生产环境。通过构建一个在线商店的实战项目,您已经掌握了使用Django构建复杂且可扩展的Web应用所需的关键技能。

学习建议

  1. 扩展功能:尝试为在线商店添加更多功能,如用户评价、产品分类、搜索功能等,进一步巩固所学知识。
  2. 探索Django REST框架:学习如何使用Django REST框架构建RESTful API,扩展应用的功能和可用性。
  3. 优化性能:研究Django应用的性能优化技巧,如缓存策略、数据库优化、异步任务处理等。
  4. 增强安全性:深入了解Web应用的安全性,学习防范常见的安全漏洞,如SQL注入、XSS攻击等。
  5. 持续部署与运维:学习如何实现持续集成和持续部署(CI/CD),提升开发和部署效率。
  6. 参与社区:通过参与Django相关的开源项目和社区活动,学习业界最佳实践,提升编程和协作能力。
  7. 深入学习:阅读官方文档和相关书籍,如《Two Scoops of Django》以进一步提升Django开发技能。

如果您有任何问题或需要进一步的帮助,请随时在评论区留言或联系相关技术社区。

相关文章:

第20篇:Python 开发进阶:使用Django进行Web开发详解

第20篇&#xff1a;使用Django进行Web开发 内容简介 在上一篇文章中&#xff0c;我们深入探讨了Flask框架的高级功能&#xff0c;并通过构建一个博客系统展示了其实际应用。本篇文章将转向Django&#xff0c;另一个功能强大且广泛使用的Python Web框架。我们将介绍Django的核…...

Elastic Agent 对 Kafka 的新输出:数据收集和流式传输的无限可能性

作者&#xff1a;来 Elastic Valerio Arvizzigno, Geetha Anne 及 Jeremy Hogan 介绍 Elastic Agent 的新功能&#xff1a;原生输出到 Kafka。借助这一最新功能&#xff0c;Elastic 用户现在可以轻松地将数据路由到 Kafka 集群&#xff0c;从而实现数据流和处理中无与伦比的可扩…...

IPoIB(IP over InfiniBand)数据接收与发送机制详解

IPoIB&#xff08;IP over InfiniBand&#xff09;是一种在InfiniBand网络上实现IP协议的技术&#xff0c;它允许在InfiniBand网络上传输IP数据包。IPoIB通过将IP数据包封装在InfiniBand的数据包中&#xff0c;实现了在InfiniBand网络上的高效通信。本文将详细分析IPoIB如何接收…...

快速更改WampServer根目录php脚本

快速更改WampServer根目录php脚本 <?php // 配置文件地址 $apacheConfPath C:\Install\CTF\Wampserver\bin\apache\apache2.4.62.1\conf\httpd.conf; $apacheConfPath2 C:\Install\CTF\Wampserver\bin\apache\apache2.4.62.1\conf\extra\httpd-vhosts.conf; // 新根目录…...

C#,入门教程(08)——基本数据类型及使用的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(07)——软件项目的源文件与目录结构https://blog.csdn.net/beijinghorn/article/details/124139947 数据类型用于指定数据体&#xff08;DataEntity&#xff0c;包括但不限于类或结构体的属性、变量、常量、函数返回值&#xff09;…...

【自定义函数】编码-查询-匹配

目录 自定义编码匹配编码匹配改进 sheet来源汇总来源汇总改进 END 自定义编码匹配 在wps vb环境写一个新的excel函数名为编码匹配&#xff0c;第一个参数指定待匹配文本所在单元格&#xff08;相对引用&#xff09;&#xff0c;第二个参数指定关键词区域&#xff08;绝对引用&…...

docker-制作镜像gcc添加jdk运行java程序

最近的项目需要使用java调用c的链接库&#xff0c;.OS文件&#xff0c;一开始准备在jdk的镜像下去安装c的环境&#xff0c;不过安装的内容很多&#xff0c;比较复杂也容易缺很多的包&#xff0c;经过实验&#xff0c;我们决定使用gcc的镜像安装jdk来正确的运行java程序。 基础镜…...

工业相机 SDK 二次开发-Sherlock插件

本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一&#xff0e;环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹&#xff0c;根据 Sherlock 版本找到…...

智慧消防营区一体化安全管控 2024 年度深度剖析与展望

在 2024 年&#xff0c;智慧消防营区一体化安全管控领域取得了令人瞩目的进展&#xff0c;成为保障营区安全稳定运行的关键力量。这一年&#xff0c;行业在政策驱动、技术创新应用、实践成果及合作交流等方面呈现出多元且深刻的发展态势&#xff0c;同时也面临着一系列亟待解决…...

On to OpenGL and 3D computer graphics

2. On to OpenGL and 3D computer graphics 声明&#xff1a;该代码来自&#xff1a;Computer Graphics Through OpenGL From Theory to Experiments&#xff0c;仅用作学习参考 2.1 First Program Square.cpp完整代码 /// // square.cpp // // OpenGL program to draw a squ…...

python实现http文件服务器访问下载

//1.py import http.server import socketserver import os import threading import sys# 获取当前脚本所在的目录 DIRECTORY os.path.dirname(os.path.abspath(__file__))# 设置服务器的端口 PORT 8000# 自定义Handler&#xff0c;将根目录设置为脚本所在目录 class MyHTT…...

Redis高阶5-布隆过滤器

Redis布隆过滤器 ​ 由一个初始值都为零的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素 目的减少内存占用方式不保存数据信息&#xff0c;只是在内存中做一个是否存在的标记flag 布隆过滤器&#xff08;英语&#xff1a;Bloom Filter&#xff0…...

Hive关于数据库的语法,warehouse,metastore

关于数据库的语法 在default数据库下,查看其他数据库的表 in 打开控制台 字体大小的设置 Hive默认的库: default, 1/4说明一共有4个库,现在只展示了1个,单击>>所有架构 数据库的删除 方法一: 语法 删除有表的数据库,加cascade 方法二 当前连接的数据库 切换当前数据库…...

Kafka 深入服务端 — 时间轮

Kafka中存在大量的延迟操作&#xff0c;比如延时生产、延时拉取和延时删除等。Kafka基于时间轮概念自定义实现了一个用于延时功能的定时器&#xff0c;来完成这些延迟操作。 1 时间轮 Kafka没有使用基于JDK自带的Timer或DelayQueue来实现延迟功能&#xff0c;因为它们的插入和…...

ubuntu系统docker环境搭建

ubuntu系统docker环境搭建 docker引擎安装 高版本docker引擎安装时已经自带有docker compose 安装参考docker官网Install Docker Engine on Ubuntu 方式一&#xff1a; 在线安装 参考apt方式安装 1、Set up Docker’s apt repository. # Add Dockers official GPG key: …...

安宝特方案 | AR在供应链管理中的应用:提升效率与透明度

随着全球化的不断深入和市场需求的快速变化&#xff0c;企业对供应链管理的要求也日益提高。如何在复杂的供应链环境中提升效率、降低成本&#xff0c;并确保信息的透明度&#xff0c;成为了各大行业亟待解决的问题。而增强现实&#xff08;AR&#xff09;技术&#xff0c;特别…...

[ Spring ] Spring Cloud Alibaba Message Stream Binder for RocketMQ 2025

文章目录 IntroduceProject StructureDeclare Plugins and ModulesApply Plugins and Add DependenciesSender PropertiesSender ApplicationSender ControllerReceiver PropertiesReceiver ApplicationReceiver Message HandlerCongratulationsAutomatically Send Message By …...

再述 Dijkstra

再述 Dijkstra 学 Dijkstra 好久了&#xff0c;今天再学了一遍&#xff0c;感觉推翻了好多自己的知识…… 定义 一种用于求非负权值的图的单源最短路径的算法。 方法 已知&#xff1a;如果要求从起始点 s 到某一个点 x 的最短路径&#xff0c;显然只能从某一个已确认为最短…...

大语言模型之prompt工程

前言 随着人工智能的快速发展&#xff0c;我们正慢慢进入AIGC的新时代&#xff0c;其中对自然语言的处理成为了智能化的关键一环&#xff0c;在这个大背景下&#xff0c;“Prompt工程”由此产生&#xff0c;并且正逐渐成为有力的工具... LLM &#xff08;Large Language Mode…...

JavaScript系列(43)--依赖注入系统实现详解

JavaScript依赖注入系统实现详解 &#x1f489; 今天&#xff0c;让我们深入探讨JavaScript的依赖注入系统实现。依赖注入是一种设计模式&#xff0c;它通过将依赖关系的创建和管理从代码中分离出来&#xff0c;提高了代码的可维护性和可测试性。 依赖注入基础概念 &#x1f…...

Mono里运行C#脚本36—加载C#类定义的成员变量和方法的数量

前面分析了加载类和基类的基本过程, 接着来分析一下加载成员变量和方法的数量。 因为我们知道C#语言定义一个类,主要就是定义成员变量,以及那些对此成员变量进行操作的方法, 所以需要使用一种方法来描述C#语言定义类的能力。 一般情况下,主要有两种类型: 普通的类,比如前…...

SWPU 2022 新生赛--web题

奇妙的MD5 进入靶场 然我们输入一个特殊的字符串&#xff0c;然后我到处翻了翻&#xff0c;发现有提示 在MD5中有两个特殊的字符串 0e215962017 //MD5加密后弱比较等于自身 ffifdyop //MD5加密后变成万能密码 这里明显就是万能密码了 输入之后就来到了这个页…...

Windows 靶机常见服务、端口及枚举工具与方法全解析:SMB、LDAP、NFS、RDP、WinRM、DNS

在渗透测试中&#xff0c;Windows 靶机通常会运行多种服务&#xff0c;每种服务都有其默认端口和常见的枚举工具及方法。以下是 Windows 靶机常见的服务、端口、枚举工具和方法的详细说明&#xff1a; 1. SMB&#xff08;Server Message Block&#xff09; 端口 445/TCP&…...

记一次Linux共享内存段排除Bug:key值为0x0000000的共享内存段删除不了

本文目录 一、问题情况二、解决方法2.1 通过kill命令删除2.2 通过程序删除 一、问题情况 今天查看共享内存段发现好多共享内存段&#xff0c;而且命令ipcrm -m <shmid>删除不了。 回想了一下&#xff0c;应该是有一些程序跑while循环&#xff0c;或者死循环&#xff0c…...

RV1126画面质量四:GOP改善画质

一&#xff0e; 什么是 GOP GOP 实际上就是两个 I 帧的间隔&#xff0c;比方说分辨率是 1920 * 1080 50 帧&#xff0c;假设 GOP 为 5&#xff0c;那就是大概 2s 插入一个 I 帧。我们再 回顾下&#xff0c;H264/H265 的帧结构。H264/H265 分别分为三种帧类型&#xff1a;I 帧、…...

手机app如何跳过无障碍权限实现弹框自动点击-ADB连接专题

手机app如何跳过无障碍权限实现弹框自动点击 --ADB连接专题 一、前言 我们在前期的时候&#xff0c;在双SIM卡进行协同外呼和SIM卡切换时&#xff0c;对如何在手机中“执行批处理脚本做自动点击”的内容进行预研&#xff0c;力图使用事件触发和坐标点击等方式来实现手机安装…...

kafka-保姆级配置说明(consumer)

bootstrap.servers #deserializer应该与producer保持对应 #key.deserializer #value.deserializer ##fetch请求返回时&#xff0c;至少获取的字节数&#xff0c;默认值为1 ##当数据量不足时&#xff0c;客户端请求将会阻塞 ##此值越大&#xff0c;客户端请求阻塞的时间越长&…...

c语言中的数组(上)

数组的概念 数组是⼀组相同类型元素的集合&#xff1b; 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0。 数组中存放的多个数据&#xff0c;类型是相同的。 数组分为⼀维数组和多维数组&#xff0c;多维数组⼀般⽐较多⻅的是⼆维数组。 数组创建 在C语言…...

20250122-正则表达式

1. 正则标记 表示一位字符&#xff1a;\\ 表示指定的一位字符&#xff1a;x 表示任意的一位字符&#xff1a;. 表示任意一位数字&#xff1a;\d 表示任意一位非数字&#xff1a;\D 表示任意一个字母&#xff1a;[a-zA-Z]&#xff08;大写或小写&#xff09; 表示任意一个…...

(回溯法 子集)leetcode78

#include<iostream> #include<string> #include<vector> //只有子集需要在每个结点收集结果&#xff0c;其余在叶子结点收集结果 using namespace std; vector<vector<int>>ans; vector<int>combine; void backtracking(int index,vector&…...

Pyecharts之图表组合与布局优化

在数据可视化中&#xff0c;我们经常需要将多个图表组合在一起&#xff0c;以展示不同维度的数据或者进行对比分析。同时&#xff0c;合理的布局能够提升图表的可读性和用户体验。Pyecharts 提供了强大的组件和方法&#xff0c;让我们可以轻松实现图表的组合和布局优化。本篇将…...

代码随想录训练营第五十六天| 108.冗余连接 109.冗余连接II

108.冗余连接 题目链接&#xff1a;卡码网题目链接&#xff08;ACM模式&#xff09; (opens new window) 讲解链接&#xff1a;代码随想录 并查集可以解决什么问题&#xff1a;两个节点是否在一个集合&#xff0c;也可以将两个节点添加到一个集合中。 引自代码随想录&#xff…...

私有包上传maven私有仓库nexus-2.9.2

一、上传 二、获取相应文件 三、最后修改自己的pom文件...

二叉搜索树中的搜索(力扣700)

首先介绍一下什么是二叉搜索树。 二叉搜索树是一个有序树&#xff1a; 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值&#xff1b;若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它的根结点的值&#xff1b;它的左、右子树也分别为二叉…...

社区养老服务平台的设计与实现(代码+数据库+LW)

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…...

高速光模块中的并行光学和WDM波分光学技术

随着AI大模型训练和推理对计算能力的需求呈指数级增长&#xff0c;AI数据中心的网络带宽需求大幅提升&#xff0c;推动了高速光模块的发展。光模块作为数据中心和高性能计算系统中的关键器件&#xff0c;主要用于提供高速和大容量的数据传输服务。 光模块提升带宽的方法有两种…...

python生成图片和pdf,快速

1、下载安装 pip install imgkit pip install pdfkit2、wkhtmltopdf工具包&#xff0c;下载安装 下载地址&#xff1a;https://wkhtmltopdf.org/downloads.html 3、生成图片 import imgkit path_wkimg rD:\app\wkhtmltopdf\bin\wkhtmltoimage.exe # 工具路径&#xff0c;安…...

浅谈在AI时代GIS的发展方向和建议

在AI时代&#xff0c;GIS&#xff08;地理信息系统&#xff09;的发展正经历着深刻的变革&#xff0c;随着人工智能技术的进步&#xff0c;GIS不再仅仅是传统的地图和空间数据处理工具&#xff0c;而是向更加智能化、自动化、精准化的方向发展。作为一名GIS开发工程师&#xff…...

【25考研】中科院软件考研复试难度分析!

中科院软件复试不需要上机&#xff01;且对专业综合能力要求较高&#xff01;提醒同学一定要认真复习&#xff01; 一、复试内容 二、参考书目 官方并未明确给出&#xff0c;建议同学参考初试书目&#xff1a; 1&#xff09;《数据结构&#xff08;C语言版&#xff09;》严蔚…...

【2024年华为OD机试】 (A卷,200分)- 计算网络信号、信号强度(JavaScriptJava PythonC/C++)

一、问题描述 题目解析 问题描述 我们有一个 m x n 的二维网格地图,每个格子可能是以下几种情况之一: 0:表示该位置是空旷的。x(正整数):表示该位置是信号源,信号强度为 x。-1:表示该位置是阻隔物,信号无法直接穿透。信号源只有一个,阻隔物可能有多个。信号在传播…...

SpringBoot整合Swagger UI 用于提供接口可视化界面

目录 一、引入相关依赖 二、添加配置文件 三、测试 四、Swagger 相关注解 一、引入相关依赖 图像化依赖 Swagger UI 用于提供可视化界面&#xff1a; <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactI…...

C语言:数据的存储

本文重点&#xff1a; 1. 数据类型详细介绍 2. 整形在内存中的存储&#xff1a;原码、反码、补码 3. 大小端字节序介绍及判断 4. 浮点型在内存中的存储解析 数据类型结构的介绍&#xff1a; 类型的基本归类&#xff1a; 整型家族 浮点家族 构造类型&#xff1a; 指针类型&…...

OpenFGA

1.什么是OpenFGA Fine-Grained Authorization 细粒度关系型授权 2.什么是细粒度授权 细粒度授权 (FGA) 意味着能够授予特定用户在特定资源中执行特定操作的权限。 精心设计的 FGA 系统允许您管理数百万个对象和用户的权限。随着系统不断添加对象并更新用户的访问权限&#…...

Kafka 入门与应用实战:吞吐量优化与与 RabbitMQ、RocketMQ 的对比

前言 在现代微服务架构和分布式系统中&#xff0c;消息队列作为解耦组件&#xff0c;承担着重要的职责。它不仅提供了异步处理的能力&#xff0c;还能确保系统的高可用性、容错性和扩展性。常见的消息队列包括 Kafka、RabbitMQ 和 RocketMQ&#xff0c;其中 Kafka 因其高吞吐量…...

单链表算法实战:解锁数据结构核心谜题——链表的回文结构

题目如下&#xff1a; 解题过程如下&#xff1a; 回文结构举例&#xff1a; 回文数字&#xff1a;12521、12321、1221…… 回文字符串&#xff1a;“abcba”、“abba”…… 并不是所有的循环嵌套的时间复杂度都是O(n^2) 可以用C写C程序&#xff1a; C里可以直接使用ListNode…...

【2024年 CSDN博客之星】我的2024年创作之旅:从C语言到人工智能,个人成长与突破的全景回顾

我的2024年创作之旅&#xff1a;从C语言到人工智能&#xff0c;个人成长与突破的全景回顾 引言 回望2024年&#xff0c;我不仅收获了技术上的成长&#xff0c;更收获了来自CSDN平台上无数粉丝、朋友以及网友们的支持与鼓励。在这条创作之路上&#xff0c;CSDN不仅是我展示技术成…...

Qt Enter和HoverEnter事件

介绍 做PC开发的过程中或多或少都会接触到鼠标的悬停事件&#xff0c;Qt中处理鼠标悬停有Enter和HoverEnter两种事件 相同点 QEvent::Enter对应QEnterEvent&#xff0c;描述的是鼠标进入控件坐标范围之内的行为&#xff0c;QEnterEvent可以抓取鼠标的位置&#xff1b;QEvent…...

Python:元组构造式和字典推导式

&#xff08;Python 元组构造式和字典推导式整理笔记&#xff09; 1. 元组构造式 1.1 创建元组 使用圆括号&#xff1a; tuple1 (1, 2.5, (three, four), [True, 5], False) print(tuple1) # 输出: (1, 2.5, (three, four), [True, 5], False) 省略圆括号&#xff1a; tup…...

科普篇 | “机架、塔式、刀片”三类服务器对比

一、引言 在互联网的世界里&#xff0c;服务器就像是默默运转的超级大脑&#xff0c;支撑着我们日常使用的各种网络服务。今天&#xff0c;咱们来聊聊服务器家族中的三位 “明星成员”&#xff1a;机架式服务器、塔式服务器和刀片式服务器。如果把互联网比作一座庞大的城市&…...

数据结构——概念与时间空间复杂度

目录 前言 一相关概念 1什么是数据结构 2什么是算法 二算法效率 1如何衡量算法效率的好坏 2算法的复杂度 三时间复杂度 1时间复杂度表示 2计算时间复杂度 2.1题一 2.2题二 2.3题三 2.4题四 2.5题五 2.6题六 2.7题七 2.8题八 四空间复杂度 1题一 2题二 3…...