手机wap网站制作免费,普通网站怎么做h5,游戏网站设计,wordpress登陆死循环一、在 D 盘创建项目目录#xff08;手动/终端均可#xff09; 方式 1#xff1a;手动操作 打开「此电脑」→ 进入 D 盘#xff1b;右键 → 新建文件夹 → 命名为 djangoblog#xff1b; 方式 2#xff1a;终端操作#xff08;推荐#xff09; 运行 # 打开CMD/Pow…一、在 D 盘创建项目目录手动/终端均可方式 1手动操作打开「此电脑」→ 进入 D 盘右键 → 新建文件夹 → 命名为djangoblog方式 2终端操作推荐运行# 打开CMD/PowerShell执行 d: mkdir djangoblog cd djangoblog二、创建虚拟环境 安装 Django运行# 1. 创建虚拟环境 python -m venv venv # 2. 激活虚拟环境Windows venv\Scripts\activate # 3. 安装Django5.2.x版本 pip install django5.2.12 # 4. 验证 Django 是否安装成功 python -m django --version三、新建 Django 项目 应用运行# 1. 新建项目注意末尾的点代表当前目录 django-admin startproject djangoblog . # 2. 新建blog应用 python manage.py startapp blog四、配置以下为所有核心文件的完整版代码1. 项目配置文件替换原有内容1D:\djangoblog\djangoblog\settings.py运行 Django settings for djangoblog project. Generated by django-admin startproject using Django 5.2.12. from pathlib import Path # Build paths inside the project like this: BASE_DIR / subdir. BASE_DIR Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production SECRET_KEY django-insecure-nt*wq1po!-jh944(%fpl9cas5m!_$hkwtnw7i6fq3rv6kw)k DEBUG True ALLOWED_HOSTS [] # Application definition INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, blog, # 注册博客应用 ] MIDDLEWARE [ django.middleware.security.SecurityMiddleware, django.contrib.sessions.middleware.SessionMiddleware, django.middleware.common.CommonMiddleware, django.middleware.csrf.CsrfViewMiddleware, django.contrib.auth.middleware.AuthenticationMiddleware, django.contrib.messages.middleware.MessageMiddleware, django.middleware.clickjacking.XFrameOptionsMiddleware, ] ROOT_URLCONF djangoblog.urls TEMPLATES [ { BACKEND: django.template.backends.django.DjangoTemplates, DIRS: [], APP_DIRS: True, OPTIONS: { context_processors: [ django.template.context_processors.debug, django.template.context_processors.request, django.contrib.auth.context_processors.auth, django.contrib.messages.context_processors.messages, ], }, }, ] WSGI_APPLICATION djangoblog.wsgi.application # Database DATABASES { default: { ENGINE: django.db.backends.sqlite3, NAME: BASE_DIR / db.sqlite3, } } # Password validation AUTH_PASSWORD_VALIDATORS [ { NAME: django.contrib.auth.password_validation.UserAttributeSimilarityValidator, }, { NAME: django.contrib.auth.password_validation.MinimumLengthValidator, }, { NAME: django.contrib.auth.password_validation.CommonPasswordValidator, }, { NAME: django.contrib.auth.password_validation.NumericPasswordValidator, }, ] # Internationalization LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai USE_I18N True USE_TZ True # Static files STATIC_URL static/ # Default primary key field type DEFAULT_AUTO_FIELD django.db.models.BigAutoField2D:\djangoblog\djangoblog\urls.py运行djangoblog URL Configuration from django.contrib import admin from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(, include(blog.urls)), # 博客首页路由 ]2. 博客应用文件替换 / 新建1D:\djangoblog\blog\models.py运行from django.db import models from django.contrib.auth.models import User from django.utils import timezone # 分类模型 class Category(models.Model): name models.CharField(分类名, max_length100) parent models.ForeignKey( self, nullTrue, blankTrue, on_deletemodels.CASCADE, related_namechildren, verbose_name父分类 ) class Meta: verbose_name 分类 verbose_name_plural 分类 ordering [id] def __str__(self): return self.name # 标签模型 class Tag(models.Model): name models.CharField(标签名, max_length50, uniqueTrue) class Meta: verbose_name 标签 verbose_name_plural 标签 ordering [id] def __str__(self): return self.name # 文章模型 class Post(models.Model): title models.CharField(标题, max_length200, uniqueTrue) content models.TextField(内容) excerpt models.CharField(摘要, max_length200, blankTrue, help_text可选不填则自动截取内容前200字) category models.ForeignKey( Category, on_deletemodels.CASCADE, related_nameposts, verbose_name分类 ) tags models.ManyToManyField( Tag, blankTrue, related_nameposts, verbose_name标签 ) author models.ForeignKey( User, on_deletemodels.CASCADE, related_nameposts, verbose_name作者 ) created_time models.DateTimeField(创建时间, defaulttimezone.now) updated_time models.DateTimeField(更新时间, auto_nowTrue) views models.PositiveIntegerField(浏览量, default0, editableFalse) class Meta: verbose_name 文章 verbose_name_plural 文章 ordering [-created_time] def __str__(self): return self.title # 自动生成摘要 def save(self, *args, **kwargs): if not self.excerpt: self.excerpt self.content[:200].replace(\n, ).replace(\r, ) super().save(*args, **kwargs) # 增加浏览量 def increase_views(self): self.views 1 self.save(update_fields[views])2D:\djangoblog\blog\admin.py运行from django.contrib import admin from .models import Post, Category, Tag # 自定义分类Admin admin.register(Category) class CategoryAdmin(admin.ModelAdmin): list_display [name, parent, id] search_fields [name] list_per_page 10 # 自定义标签Admin admin.register(Tag) class TagAdmin(admin.ModelAdmin): list_display [name, id] search_fields [name] list_per_page 10 # 自定义文章Admin admin.register(Post) class PostAdmin(admin.ModelAdmin): list_display [title, category, author, created_time, updated_time, views, id] list_filter [category, tags, created_time] search_fields [title, content] autocomplete_fields [tags] readonly_fields [updated_time, views] fieldsets [ (基础信息, {fields: [title, content, excerpt]}), (分类与标签, {fields: [category, tags]}), (作者与时间, {fields: [author, created_time, updated_time, views], classes: [collapse]}) ] list_per_page 103D:\djangoblog\blog\views.py运行from django.views.generic import ListView, DetailView from .models import Post, Category, Tag # 博客首页文章列表 class IndexView(ListView): model Post template_name blog/index.html context_object_name posts paginate_by 10 def get_context_data(self, **kwargs): context super().get_context_data(** kwargs) context[categories] Category.objects.all() context[recent_posts] Post.objects.all()[:10] context[hot_posts] Post.objects.all().order_by(-views)[:10] return context # 文章详情页 class PostDetailView(DetailView): model Post template_name blog/post.html context_object_name post def get_object(self, querysetNone): obj super().get_object(queryset) obj.increase_views() return obj def get_context_data(self, **kwargs): context super().get_context_data(** kwargs) context[categories] Category.objects.all() context[recent_posts] Post.objects.all()[:10] context[hot_posts] Post.objects.all().order_by(-views)[:10] return context4 新建D:\djangoblog\blog\urls.py运行from django.urls import path from . import views app_name blog urlpatterns [ path(, views.IndexView.as_view(), nameindex), path(post/int:pk/, views.PostDetailView.as_view(), namedetail), ]3. 模板文件全部新建1D:\djangoblog\blog\templates\blog\base.html预览!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title{% block title %}Django博客{% endblock %}/title style * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Microsoft YaHei, sans-serif; color: #333; line-height: 1.6; background-color: #f8f9fa; } a { text-decoration: none; color: #2385bb; transition: color 0.2s; } a:hover { color: #1a6899; } ul { list-style: none; } .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; } /* 头部样式 */ header { background-color: #fff; border-bottom: 1px solid #eee; padding: 20px 0; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .header-content { display: flex; flex-direction: column; gap: 10px; } .blog-title { font-size: 28px; font-weight: bold; color: #333; } .blog-desc { font-size: 14px; color: #666; } .nav { margin-top: 10px; } .nav a { margin-right: 25px; font-size: 15px; color: #666; } .nav a:hover { color: #2385bb; } /* 主体内容区 */ .main-content { display: flex; gap: 30px; margin: 30px 0; } .main { flex: 2; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); } .sidebar { flex: 1; display: flex; flex-direction: column; gap: 20px; } .sidebar-box { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); } .sidebar-title { font-size: 16px; font-weight: bold; color: #666; padding-bottom: 10px; border-bottom: 1px solid #eee; margin-bottom: 15px; } .sidebar-list li { margin-bottom: 10px; font-size: 14px; } .sidebar-list a { color: #666; } .sidebar-list a:hover { color: #2385bb; text-decoration: underline; } /* 文章列表样式 */ .post-item { margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid #eee; } .post-item:last-child { border-bottom: none; } .post-title { font-size: 20px; margin-bottom: 10px; } .post-comment { font-size: 13px; color: #999; margin-bottom: 8px; } .post-excerpt { font-size: 14px; color: #666; margin-bottom: 10px; line-height: 1.8; } .post-meta { font-size: 12px; color: #999; } /* 详情页样式 */ .post-detail h1 { font-size: 24px; margin-bottom: 20px; color: #333; border-bottom: 1px solid #eee; padding-bottom: 10px; } .post-detail-meta { font-size: 13px; color: #666; margin-bottom: 20px; } .post-content { font-size: 15px; color: #333; line-height: 1.8; } .post-content p { margin-bottom: 15px; } /* 空数据样式 */ .empty-tip { text-align: center; padding: 50px 0; color: #999; font-size: 16px; } /style /head body header div classcontainer header-content h1 classblog-titledjangoblog/h1 p classblog-desc基于Django的极简博客系统/p nav classnav a href{% url blog:index %}首页/a a href#我是父类目/a a href#文章归档/a /nav /div /header div classcontainer main-content div classmain {% block content %}{% endblock %} /div div classsidebar !-- 热门文章 -- div classsidebar-box h3 classsidebar-titleVIEWS/h3 ul classsidebar-list {% for post in hot_posts %} lia href{% url blog:detail post.pk %}{{ post.title }} - {{ post.views }} views/a/li {% empty %} li暂无热门文章/li {% endfor %} /ul /div !-- 分类目录 -- div classsidebar-box h3 classsidebar-title分类目录/h3 ul classsidebar-list {% for cat in categories %} lia href#{{ cat.name }}/a/li {% empty %} li暂无分类/li {% endfor %} /ul /div !-- 近期文章 -- div classsidebar-box h3 classsidebar-title近期文章/h3 ul classsidebar-list {% for post in recent_posts %} lia href{% url blog:detail post.pk %}{{ post.title }}/a/li {% empty %} li暂无近期文章/li {% endfor %} /ul /div /div /div /body /html2D:\djangoblog\blog\templates\blog\index.html预览{% extends blog/base.html %} {% block title %}djangoblog - 首页{% endblock %} {% block content %} {% for post in posts %} div classpost-item h2 classpost-titlea href{% url blog:detail post.pk %}{{ post.title }}/a/h2 p classpost-comment评论/p p classpost-excerpt{{ post.excerpt }}/p a href{% url blog:detail post.pk %}Read more/a div classpost-meta 发布于 {{ post.category.name }} 并标记为 {% for tag in post.tags.all %} {{ tag.name }}{% if not forloop.last %}, {% endif %} {% empty %} 无标签 {% endfor %} 由 {{ post.author.username }} 在 {{ post.created_time|date:Y-m-d }} /div /div {% empty %} div classempty-tip 暂无文章快去Admin后台添加吧br a href{% url admin:index %} stylecolor: #2385bb;点击进入Admin后台/a /div {% endfor %} {% endblock %}3D:\djangoblog\blog\templates\blog\post.html预览{% extends blog/base.html %} {% block title %}{{ post.title }} - djangoblog{% endblock %} {% block content %} div classpost-detail h1{{ post.title }}/h1 div classpost-detail-meta 分类{{ post.category.name }} | 标签{% for tag in post.tags.all %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% empty %}无标签{% endfor %} | 作者{{ post.author.username }} | 发布时间{{ post.created_time|date:Y-m-d H:i }} | 最后更新{{ post.updated_time|date:Y-m-d H:i }} | 浏览量{{ post.views }} /div div classpost-content {{ post.content|linebreaksbr }} /div /div {% endblock %}五、执行项目初始化命令按顺序运行# 1. 确保在D:\djangoblog目录下且虚拟环境已激活 d: cd djangoblog venv\Scripts\activate # 2. 生成数据库迁移文件 python manage.py makemigrations # 3. 执行数据库迁移 python manage.py migrate # 4. 创建超级用户按提示输入用户名、密码 python manage.py createsuperuser # 5. 启动开发服务器 python manage.py runserver六、访问与测试Admin 后台添加数据访问http://127.0.0.1:8000/admin/登录超级用户先添加「分类」「标签」再添加「文章」选择分类、标签、作者访问博客首页http://127.0.0.1:8000/访问文章详情点击文章标题 → 进入详情页浏览量自动 1。 完整目录结构最终D:\djangoblog/ ← 项目根目录 ├── venv/ # 虚拟环境目录自动生成 │ ├── Include/ │ ├── Lib/ │ ├── Scripts/ │ └── pyvenv.cfg ├── djangoblog/ # 项目配置目录startproject生成 │ ├── __init__.py # 空文件标识Python包 │ ├── asgi.py # ASGI配置默认生成无需修改 │ ├── settings.py # 项目核心配置已提供完整版代码 │ ├── urls.py # 项目级路由已提供完整版代码 │ └── wsgi.py # WSGI配置默认生成无需修改 ├── blog/ # 博客应用目录startapp生成 │ ├── __init__.py # 空文件标识Python包 │ ├── admin.py # Admin后台配置已提供完整版代码 │ ├── apps.py # 应用配置默认生成无需修改 │ ├── migrations/ # 数据库迁移文件执行makemigrations后自动生成 │ │ ├── __init__.py │ │ └── 0001_initial.py # 模型迁移文件自动生成 │ ├── models.py # 数据模型已提供完整版代码 │ ├── tests.py # 测试文件默认生成可忽略 │ ├── urls.py # 应用级路由需新建已提供代码 │ ├── views.py # 视图逻辑已提供完整版代码 │ └── templates/ # 模板目录需手动创建 │ └── blog/ # 应用专属模板子目录避免命名冲突 │ ├── base.html # 基础布局模板已提供完整版代码 │ ├── index.html # 博客首页模板已提供完整版代码 │ └── post.html # 文章详情模板已提供完整版代码 ├── db.sqlite3 # SQLite数据库文件执行migrate后自动生成 └── manage.py # Django管理脚本startproject自动生成七、 总结项目整体概述DjangoBlog 是基于Django 5.2开发的极简博客系统实现了博客核心功能文章发布 / 管理、分类 / 标签体系、文章详情展示、浏览量统计、侧边栏热门 / 近期文章展示等。项目遵循 Django 经典的 MVTModel-View-Template设计模式结构清晰、易扩展适合 Django 初学者学习和二次开发。1. MVT 架构拆解核心设计Django 摒弃了传统 MVC 的命名采用 MVT 架构三者分工明确1Model模型数据层blog/models.py作用定义数据结构负责与数据库交互增删改查是整个项目的「数据基石」。核心模型及功能Category分类管理博客文章分类支持多级分类父分类关联Tag标签为文章添加标签实现内容多维度归类Post文章核心模型包含标题、内容、摘要、分类、标签、作者、发布时间、浏览量等字段自动生成摘要未填写摘要时截取内容前 200 字浏览量统计访问详情页时自动 1按发布时间倒序排序最新文章优先展示。关键特性基于 Django ORM 实现数据库操作无需手写 SQL通过ForeignKey/ManyToManyField实现模型关联文章 - 分类一对多、文章 - 标签多对多内置__str__方法、Meta类优化 Admin 后台展示和数据排序。2View视图逻辑层blog/views.py作用处理用户请求调用模型获取数据传递给模板渲染是「数据与视图的桥梁」。核心视图及功能IndexView首页视图继承 Django 通用列表视图ListView批量获取文章数据分页展示每页 10 篇传递侧边栏数据所有分类、近期文章、热门文章PostDetailView详情页视图继承 Django 通用详情视图DetailView获取单篇文章数据访问时自动增加文章浏览量传递侧边栏通用数据保证页面布局统一。关键特性采用类视图Class-Based View简化重复代码重写get_context_data传递额外数据满足页面多维度展示需求重写get_object实现浏览量统计逻辑与视图解耦。3Template模板展示层blog/templates/blog/作用负责页面渲染接收视图传递的数据生成最终的 HTML 页面展示给用户。核心模板及分工base.html基础模板定义博客全局布局头部导航、主体容器、侧边栏封装通用样式和结构其他模板通过extends继承减少重复代码预留{% block content %}块供子模板填充个性化内容index.html首页模板继承base.html渲染文章列表循环展示文章标题、摘要、发布信息空数据时提示用户添加文章post.html详情页模板继承base.html渲染单篇文章完整内容展示文章元信息分类、标签、发布时间、浏览量通过linebreaksbr过滤器处理内容换行保证排版美观。关键特性模板继承实现布局复用降低维护成本模板标签 / 过滤器动态渲染数据如{% for %}循环、|date格式化时间静态样式内联保证页面独立运行无需额外引入 CSS 文件。2. 路由层URLconf请求分发补充Django 中路由是 MVT 的「入口」负责将用户请求分发到对应视图1项目级路由djangoblog/urls.py配置 Admin 后台路由admin/分发博客核心请求到应用级路由 → include(blog.urls)2应用级路由blog/urls.py首页 → IndexView.as_view()文章详情post/int:pk/ → PostDetailView.as_view()定义命名空间app_name blog避免路由命名冲突。3. Admin 后台数据管理补充通过blog/admin.py自定义 Admin 后台实现数据可视化管理注册Category/Tag/Post模型支持分类 / 标签 / 文章的增删改查自定义列表展示字段、筛选条件、搜索功能提升管理效率配置字段集fieldsets优化文章编辑页面布局只读字段如浏览量、更新时间防止误修改核心数据。4. 核心功能总结表格模块核心功能数据层M分类 / 标签 / 文章数据建模、ORM 操作逻辑层V文章列表 / 详情展示、浏览量统计、分页展示层T响应式布局、数据动态渲染、样式美化路由层请求分发、URL 设计Admin 后台数据可视化管理5. 项目运行流程用户访问http://127.0.0.1:8000/→ 路由分发到IndexViewIndexView调用Post模型获取文章列表 侧边栏数据视图将数据传递给index.html模板渲染生成 HTML 页面用户点击文章标题 → 路由分发到PostDetailView→ 获取单篇文章数据 → 渲染post.html管理员访问http://127.0.0.1:8000/admin/→ 管理分类 / 标签 / 文章数据。该项目完整体现了 Django MVT 架构的「高内聚、低耦合」特性模型专注数据、视图专注逻辑、模板专注展示各模块独立且协作符合 Django 「不要重复造轮子」的设计哲学。【附页】代码仓库北冥有羽/djangobloghttps://gitee.com/Zhang-Siyu0066/djangoblog