搭建基于Django的博客系统增加广告轮播图(三)

上一篇:ChatGPT搭建博客Django的web网页添加用户系统(二)
下一篇:搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL(四)

功能概述

  1. 增加轮播图显示广告信息。

需求详细描述

1. 增加轮播图显示广告信息

  • 描述: 在博客首页添加轮播图功能,显示广告信息或推荐内容。
  • 功能要求:
    • 轮播图位置:位于页面顶部。
    • 图片上传功能:管理员可以在后台上传和管理轮播图图片。
    • 支持多张图片轮播,每张图片可以包含链接。
    • 自动轮播和手动切换图片。
  • 用户故事:
    • 作为访客,我希望看到首页的轮播图以获取最新的广告或推荐内容。
    • 作为管理员,我希望能够上传和管理轮播图图片。

文件结构图

添加轮播图功能后的文件结构图,其中包含Django项目和应用的主要文件和目录。

myblog/
├── blog/
│   ├── migrations/
│   ├── static/
│   ├── templates/
│   │   ├── blog/
│   │   │   ├── post_list.html
│   │   ├── registration/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
│   ├── forms.py
├── myblog/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── media/
│   ├── carousel_images/
├── manage.py

在博客首页添加轮播图功能的具体实现

为了在Django博客首页添加轮播图功能,我们需要完成以下步骤:

  1. 设置模型 (Models)
    • 创建一个模型用于存储轮播图图片和相关信息。
  2. 创建视图 (Views)
    • 在视图中获取轮播图数据,并传递给模板。
  3. 更新模板 (Templates)
    • 修改首页模板,添加轮播图的HTML和CSS。
  4. 管理后台配置 (Admin)
    • 配置Django Admin管理轮播图内容。

1. 设置模型 (Models)

首先,创建一个新的模型 Carousel 来存储轮播图图片及其相关信息。

# blog/models.py

from django.db import models

class Carousel(models.Model):
    title = models.CharField(max_length=200)
    image = models.ImageField(upload_to='carousel_images/')
    link = models.URLField(blank=True, null=True)
    active = models.BooleanField(default=True)

    def __str__(self):
        return self.title

然后,运行 makemigrationsmigrate 命令来创建数据库表。

bash复制代码python manage.py makemigrations
python manage.py migrate

2. 创建视图 (Views)

在视图中获取所有激活的轮播图数据,并传递给模板。

# blog/views.py

from django.shortcuts import render
from .models import Carousel, Post

def post_list(request):
    posts = Post.objects.all()
    carousels = Carousel.objects.filter(active=True)
    return render(request, 'blog/post_list.html', {'posts': posts, 'carousels': carousels})

3. 更新模板 (Templates)

post_list.html 中添加轮播图的HTML和CSS。

<!-- blog/templates/blog/post_list.html -->

<!DOCTYPE html>
<html>
<head>
    <title>Blog</title>
    <!-- 引入Bootstrap样式 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <!-- 轮播图开始 -->
        <div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
            <ol class="carousel-indicators">
                {% for carousel in carousels %}
                <li data-target="#carouselExampleIndicators" data-slide-to="{{ forloop.counter0 }}" class="{% if forloop.first %}active{% endif %}"></li>
                {% endfor %}
            </ol>
            <div class="carousel-inner">
                {% for carousel in carousels %}
                <div class="carousel-item {% if forloop.first %}active{% endif %}">
                    <img src="{{ carousel.image.url }}" class="d-block w-100" alt="{{ carousel.title }}">
                    {% if carousel.link %}
                    <a href="{{ carousel.link }}" target="_blank">
                        <div class="carousel-caption d-none d-md-block">
                            <h5>{{ carousel.title }}</h5>
                        </div>
                    </a>
                    {% else %}
                    <div class="carousel-caption d-none d-md-block">
                        <h5>{{ carousel.title }}</h5>
                    </div>
                    {% endif %}
                </div>
                {% endfor %}
            </div>
            <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
                <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                <span class="sr-only">Previous</span>
            </a>
            <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
                <span class="carousel-control-next-icon" aria-hidden="true"></span>
                <span class="sr-only">Next</span>
            </a>
        </div>
        <!-- 轮播图结束 -->

        <!-- 其他内容 -->
        <div class="row mt-5">
            <div class="col-md-9">
                <h1>Blog Posts</h1>
                <ul>
                    {% for post in posts %}
                    <li>
                        <h2>
                            <a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a>
                        </h2>
                        <p>{{ post.content }}</p>
                        <p>Published by: {{ post.author.username }}</p>
                        {% if user.is_authenticated and user == post.author %}
                        <a href="{% url 'post_edit' post.pk %}">Edit</a>
                        <a href="{% url 'post_delete' post.pk %}">Delete</a>
                        {% endif %}
                    </li>
                    {% endfor %}
                </ul>
                {% block content %}
                {% endblock %}
            </div>
        </div>
    </div>

    <!-- 引入Bootstrap的JavaScript -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

4. 管理后台配置 (Admin)

在Django Admin中配置管理轮播图内容。

# blog/admin.py

from django.contrib import admin
from .models import Post, Carousel

@admin.register(Carousel)
class CarouselAdmin(admin.ModelAdmin):
    list_display = ('title', 'active')
    list_filter = ('active',)
    search_fields = ('title',)

settings.py 中确保已正确配置 MEDIA_URLMEDIA_ROOT 以支持图片上传。

# settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

在主URL配置中添加对媒体文件的处理。

# myblog/urls.py

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

解决问题

报错<class 'blog.admin.CarouselAdmin'>: (admin.E108) The value of 'list_display[1]' refers to 'active', which is not a callable, an attribute of 'CarouselAdmin', or an attribute or method on 'blog.Carousel'.

在这里插入图片描述

Carousel 模型中没有定义 active 字段。你需要确保在 Carousel 模型中有 active 字段,然后在 admin.py 中正确地使用它。

1. 更新 Carousel 模型

如果你想要一个 active 字段来表示某个轮播图是否启用,你可以在模型中添加这个字段。

models.py
python复制代码from django.db import models

class Carousel(models.Model):
    image = models.ImageField(upload_to='carousel_images/')
    title = models.CharField(max_length=100, blank=True)
    description = models.CharField(max_length=255, blank=True)
    link = models.URLField(blank=True)
    active = models.BooleanField(default=True)  # 添加active字段

    def __str__(self):
        return self.title if self.title else "Carousel Image"

2. 迁移数据库

在添加字段后,需要运行迁移命令来更新数据库:

bash复制代码python manage.py makemigrations
python manage.py migrate

3. 更新 admin.py

现在你可以在 admin.py 中使用 active 字段。

admin.py
python复制代码from django.contrib import admin
from .models import Carousel

class CarouselAdmin(admin.ModelAdmin):
    list_display = ('title', 'active')  # 添加active字段到list_display
    list_filter = ('active',)           # 添加active字段到list_filter

admin.site.register(Carousel, CarouselAdmin)

4. 确认模板中的更新

确保你的模板和视图中也考虑了 active 字段。例如,在显示轮播图时只显示 activeTrue 的图片:

views.py
python复制代码from django.shortcuts import render
from .models import Carousel, Post, CustomUser

def post_list(request):
    posts = Post.objects.all()
    carousels = Carousel.objects.filter(active=True)  # 只获取active的轮播图
    users = CustomUser.objects.all()
    return render(request, 'blog/post_list.html', {'posts': posts, 'carousels': carousels, 'users': users})

这样,Carousel 模型现在包含 active 字段,admin.py 也正确配置了显示和过滤选项。请确保已经正确运行了数据库迁移命令来更新数据库结构。

报错 raise AlreadyRegistered(msg) django.contrib.admin.exceptions.AlreadyRegistered: The model Carousel is already registered with 'blog.CarouselAdmin'.

上传图片数据

打开控制台能看到Carousels,上传文件

在这里插入图片描述

在这里插入图片描述

上传完成5张图,在/media/carousel_images目录下看到上传的图片如下带后缀:

在这里插入图片描述

效果如下:

在这里插入图片描述

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

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

相关文章

python解决flask启动的同时启动定时任务

业务场景描述&#xff1a;在常规的开发中&#xff0c;我们开发接口服务&#xff0c;一般会将数据放在数据库、文件等第三方文件&#xff0c;启动服务后&#xff0c;服务到后台数据库中加载数据&#xff0c;这样做的好处当然是开发会更加便利以及数据的可复用性较高&#xff0c;…

一键实现文件夹批量高效重命名:轻松运用随机一个字母命名,让文件管理焕然一新!

在数字化时代&#xff0c;文件夹管理是我们日常生活和工作中不可或缺的一部分。然而&#xff0c;随着文件数量的不断增加&#xff0c;文件夹命名的繁琐和重复成为了一个让人头疼的问题。你是否曾因为手动一个个重命名文件夹而感到枯燥乏味&#xff1f;你是否曾渴望有一种方法能…

arm cortex-m架构 SVC指令详解以及其在freertos的应用

1. 前置知识 本文基于arm cortex-m架构描述&#xff0c; 关于arm cortex-m的一些基础知识可以参考我另外几篇文章&#xff1a; arm cortex-m 架构简述arm异常处理分析c语言函数调用规范-基于arm 分析 2 SVC指令 2.1 SVC指令位域表示 bit15 - bit12&#xff1a;条件码&#…

深入分析 Android BroadcastReceiver (一)

文章目录 深入分析 Android BroadcastReceiver (一)1. Android BroadcastReceiver 设计说明1.1 BroadcastReceiver 的主要用途 2. BroadcastReceiver 的工作机制2.1 注册 BroadcastReceiver2.1.1 静态注册2.1.2 动态注册 3. BroadcastReceiver 的生命周期4. 实现和使用 Broadca…

Android下HWC以及drm_hwcomposer普法(上)

Android下HWC以及drm_hwcomposer普法(上) 引言 按摩得全套&#xff0c;错了&#xff0c;做事情得全套&#xff0c;普法分析也是如此。drm_hwcomposer如果对Android图形栈有一定研究的童鞋们应该知道它是Android提供的一个的图形后端合成处理HAL模块的实现。但是在分析这个之前…

yolov8使用:数据格式转换(目标检测、图像分类)多目标跟踪

安装 yolov8地址&#xff1a;https://github.com/ultralytics/ultralytics git clone https://github.com/ultralytics/ultralytics.git安装环境&#xff1a; pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple目标检测 标注格式转换 若使用 labelimg…

sql注入-布尔盲注

布尔盲注&#xff08;Boolean Blind SQL Injection&#xff09;是一种SQL注入攻击技术&#xff0c;用于在无法直接获得查询结果的情况下推断数据库信息&#xff1b;它通过发送不同的SQL查询来观察应用程序的响应&#xff0c;进而判断查询的真假&#xff0c;并逐步推断出有用的信…

微服务学习Day9

文章目录 分布式事务seata引入理论基础CAP定理BASE理论 初识Seata动手实践XA模式AT模式TCC模式SAGA模式 高可用 分布式事务seata 引入 理论基础 CAP定理 BASE理论 初识Seata 动手实践 XA模式 AT模式 TCC模式 Service Slf4j public class AccountTCCServiceImpl implements A…

C语言 | Leetcode C语言题解之第126题单词接龙II

题目&#xff1a; 题解&#xff1a; char** list; int** back; int* backSize;// DFS uses backtrack information to construct results void dfs(char*** res, int* rSize, int** rCSizes, int* ans, int last, int retlevel) {int i ans[last];if (i 0) {res[*rSize] (c…

DALL·E 2详解:人工智能如何将您的想象力变为现实!

引言 DALLE 2是一个基于人工智能的图像生成模型&#xff0c;它通过理解自然语言描述来生成匹配这些描述的图像。这一模型的核心在于其创新的两阶段工作流程&#xff0c;首先是将文本描述转换为图像表示&#xff0c;然后是基于这个表示生成具体的图像。 下面详细介绍DALL-E2的功…

Vivado Design Suite一级物件

Vivado Design Suite一级物件 按设计过程导航内容 Xilinx文档围绕一组标准设计流程进行组织&#xff0c;以帮助您 查找当前开发任务的相关内容。本文件涵盖 以下设计过程&#xff1a; •硬件、IP和平台开发&#xff1a;为硬件创建PL IP块 平台&#xff0c;创建PL内核&#xff0…

HTML的标签(标题、段落、文本、图片、列表)

HTML的标签1 标题标签&#xff1a;段落标签&#xff1a;文本标签&#xff1a;图片标签:列表标签&#xff1a;有序列表&#xff1a;无序列表&#xff1a;定义列表&#xff1a;列表案例&#xff1a; 标题标签&#xff1a; 标签&#xff1a;h1~h6 注意&#xff1a;如果使用无效标…

C语言怎样写数据⽂件,使之可以在不同字⼤⼩、 字节顺序或浮点格式的机器上读⼊?

一、问题 怎样写数据⽂件&#xff0c;使之可以在不同字⼤⼩、字节顺序或浮点格式的机器上读⼊&#xff0c;也就是说怎样写⼀个可移植性好的数据⽂件&#xff1f; 二、解答 最好的移植⽅法是使⽤⽂本⽂件&#xff0c;它的每⼀字节放⼀个 ASCII 代码&#xff0c;代表⼀个字符。 …

从JS角度直观理解递归的本质

让我们写一个函数 pow(x, n)&#xff0c;它可以计算 x 的 n 次方。换句话说就是&#xff0c;x 乘以自身 n 次。 有两种实现方式。 迭代思路&#xff1a;使用 for 循环&#xff1a; function pow(x, n) {let result 1;// 在循环中&#xff0c;用 x 乘以 result n 次for (let i…

短时间内如何顺利通过 Java 面试?

今天我们来探讨一个重要的话题&#xff1a;短时间内如何顺利通过 Java 面试&#xff1f; 在此之前&#xff0c;我正在精心编写一套完全面向小白的 Java 自学教程&#xff0c;我相信这套教程会非常适合正在努力提升的你。教程里面涵盖了丰富全面的编程教学内容、详细生动的视频…

2.8Flowmap的实现

一、Flowmap 是什么 半条命2中水的流动 求生之路2中的水的流动 这种方式原理简单&#xff0c;容易实现&#xff0c;运算量少&#xff0c;如今也还在使用 1.flowmap的实质 Flow map(流向图) &#xff0c;一张记录了2D向量信息的纹理&#xff0c;Flow map上的颜色(通常为RG通道…

Python知识点14---被规定的资源

提前说一点&#xff1a;如果你是专注于Python开发&#xff0c;那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了&#xff0c;而如果你和作者一样只是操作其他技术的Python API那就足够了。 在Python中被规定的东西不止有常识中的那些关键字、构造器等编程语言…

Vue3-Ref Reactive toRef toRefs对比学习、标签ref与组件ref

响应式数据&#xff1a; Ref 作用&#xff1a;定义响应式变量。 语法&#xff1a;let xxx ref(初始值)(里面可以是任何规定内类型、数组等)。 返回值&#xff1a;一个RefImpl的实例对象&#xff0c;简称ref对象或ref&#xff0c;ref对象的value属性是响应式的。 注意点&am…

公网如何访问内网?

公网和内网已经成为我们生活中不可或缺的存在。由于内网的安全性考虑&#xff0c;公网无法直接访问内网资源。如何实现公网访问内网呢&#xff1f;本文将介绍一种名为【天联】的私有通道技术&#xff0c;通过安全加密&#xff0c;保障数据传输的安全性。 【天联】私有通道技术 …

利用Python处理DAX多条件替换

小A&#xff1a;白茶&#xff0c;救命啊~~~ 白茶&#xff1a;什么情况&#xff1f; 小A&#xff1a;是这样的&#xff0c;最近不是临近项目上线嘛&#xff0c;有一大波度量值需要进行类似的调整&#xff0c;一个两个倒没啥&#xff0c;600多个&#xff0c;兄弟&#xff0c;救命…