上一篇: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.pyfrom django.db import modelsclass 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.pyfrom django.shortcuts import render
from .models import Carousel, Postdef 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.pyfrom 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.pyMEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
在主URL配置中添加对媒体文件的处理。
# myblog/urls.pyfrom django.conf import settings
from django.conf.urls.static import staticurlpatterns = [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 modelsclass 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 Carouselclass CarouselAdmin(admin.ModelAdmin):list_display = ('title', 'active') # 添加active字段到list_displaylist_filter = ('active',) # 添加active字段到list_filteradmin.site.register(Carousel, CarouselAdmin)
4. 确认模板中的更新
确保你的模板和视图中也考虑了 active
字段。例如,在显示轮播图时只显示 active
为 True
的图片:
views.py
python复制代码from django.shortcuts import render
from .models import Carousel, Post, CustomUserdef 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
目录下看到上传的图片如下带后缀:
效果如下: