上一篇:ChatGPT搭建博客Django的web网页添加用户系统(二)
下一篇:搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL(四)
功能概述
- 增加轮播图显示广告信息。
需求详细描述
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博客首页添加轮播图功能,我们需要完成以下步骤:
- 设置模型 (Models)
- 创建一个模型用于存储轮播图图片和相关信息。
- 创建视图 (Views)
- 在视图中获取轮播图数据,并传递给模板。
- 更新模板 (Templates)
- 修改首页模板,添加轮播图的HTML和CSS。
- 管理后台配置 (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
然后,运行 makemigrations
和 migrate
命令来创建数据库表。
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_URL
和 MEDIA_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
字段。例如,在显示轮播图时只显示 active
为 True
的图片:
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
目录下看到上传的图片如下带后缀:
效果如下: