搭建基于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目录下看到上传的图片如下带后缀:

在这里插入图片描述

效果如下:

在这里插入图片描述

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值