0
# Views and URL Handling
1
2
Complete set of class-based views for displaying blog content including detail views, list views, archive views, and filtered views with multilingual and SEO support.
3
4
## Imports
5
6
```python
7
from typing import Dict, Any, List, Optional
8
from django.views.generic import DetailView, ListView
9
from django.urls import path, URLPattern
10
from django.db.models import QuerySet
11
from django.http import HttpRequest
12
from djangocms_blog.models import Post, BlogCategory
13
from djangocms_blog.views import (
14
PostDetailView, PostListView, PostArchiveView,
15
TaggedListView, AuthorEntriesView, CategoryEntriesView,
16
BaseBlogView, BaseBlogListView
17
)
18
from djangocms_blog.feeds import LatestEntriesFeed
19
from djangocms_blog.sitemaps import BlogSitemap
20
```
21
22
## Capabilities
23
24
### Base View Classes
25
26
Foundation view classes providing common functionality for blog views.
27
28
```python { .api }
29
class BaseBlogView(AppConfigMixin, ViewUrlMixin):
30
"""
31
Base view for blog functionality with app config mixin.
32
33
Attributes:
34
- model: Post
35
- queryset: Post.objects.published()
36
- context_object_name: 'post'
37
"""
38
39
def get_view_url(self) -> str:
40
"""Return view URL for current request."""
41
42
def get_queryset(self):
43
"""Return filtered queryset for current app config."""
44
45
class BaseBlogListView(BaseBlogView):
46
"""
47
Base list view for blog items.
48
49
Attributes:
50
- paginate_by: From get_setting('PAGINATION')
51
- context_object_name: 'post_list'
52
"""
53
54
def get_context_data(self, **kwargs) -> Dict[str, Any]:
55
"""Add extra context for list views."""
56
```
57
58
### Post Detail View
59
60
Detail view for individual blog posts with multilingual slug support and SEO optimization.
61
62
```python { .api }
63
class PostDetailView(TranslatableSlugMixin, BaseBlogView, DetailView):
64
"""
65
Detail view for individual blog posts.
66
67
Features:
68
- Multilingual slug handling via TranslatableSlugMixin
69
- SEO meta tag support
70
- Related posts context
71
- Comment integration
72
- Social sharing data
73
"""
74
75
slug_field: str = 'slug'
76
77
def get_object(self, queryset=None):
78
"""Get post object with language handling."""
79
80
def get_context_data(self, **kwargs) -> Dict[str, Any]:
81
"""
82
Add extra context including:
83
- Related posts
84
- Categories
85
- Tags
86
- Meta information
87
- Previous/next posts
88
"""
89
90
def get_queryset(self):
91
"""Return published posts queryset."""
92
```
93
94
### List Views
95
96
Various list views for displaying filtered sets of blog posts.
97
98
```python { .api }
99
class PostListView(BaseBlogListView, ListView):
100
"""
101
List view for blog posts.
102
103
Features:
104
- Pagination support
105
- Category filtering
106
- Tag filtering
107
- Date filtering
108
- Search functionality
109
"""
110
111
template_name: str = 'djangocms_blog/post_list.html'
112
113
def get_queryset(self):
114
"""Return filtered post queryset."""
115
116
def get_context_data(self, **kwargs) -> Dict[str, Any]:
117
"""Add pagination and filter context."""
118
119
class PostArchiveView(BaseBlogListView, ListView):
120
"""
121
Archive view for blog posts by date.
122
123
URL patterns support:
124
- /archive/YYYY/
125
- /archive/YYYY/MM/
126
- /archive/YYYY/MM/DD/
127
"""
128
129
template_name: str = 'djangocms_blog/post_archive.html'
130
date_field: str = 'date_published'
131
132
def get_queryset(self):
133
"""Return posts filtered by date parameters."""
134
135
def get_context_data(self, **kwargs) -> Dict[str, Any]:
136
"""Add date context (year, month, day)."""
137
138
class TaggedListView(BaseBlogListView, ListView):
139
"""
140
List view for posts filtered by tags.
141
142
URL: /tag/tag-slug/
143
"""
144
145
template_name: str = 'djangocms_blog/post_list.html'
146
147
def get_queryset(self):
148
"""Return posts filtered by tag slug."""
149
150
def get_context_data(self, **kwargs) -> Dict[str, Any]:
151
"""Add tag context."""
152
153
class AuthorEntriesView(BaseBlogListView, ListView):
154
"""
155
List view for posts by specific author.
156
157
URL: /author/author-username/
158
"""
159
160
template_name: str = 'djangocms_blog/post_list.html'
161
162
def get_queryset(self):
163
"""Return posts filtered by author."""
164
165
def get_context_data(self, **kwargs) -> Dict[str, Any]:
166
"""Add author context."""
167
168
class CategoryEntriesView(BaseBlogListView, ListView):
169
"""
170
List view for posts in specific category.
171
172
URL: /category/category-slug/
173
"""
174
175
template_name: str = 'djangocms_blog/post_list.html'
176
177
def get_queryset(self):
178
"""Return posts filtered by category."""
179
180
def get_context_data(self, **kwargs) -> Dict[str, Any]:
181
"""Add category context."""
182
```
183
184
### URL Configuration
185
186
The package provides complete URL configuration for all view patterns.
187
188
```python { .api }
189
# Main URL patterns (djangocms_blog.urls)
190
urlpatterns = [
191
path('', PostListView.as_view(), name='posts-latest'),
192
path('feed/', LatestEntriesFeed(), name='posts-latest-feed'),
193
path('sitemap.xml', BlogSitemap(), name='posts-sitemap'),
194
# Dynamic URL patterns based on permalink configuration
195
# Example patterns:
196
# path('<int:year>/<int:month>/<int:day>/<str:slug>/', PostDetailView.as_view(), name='post-detail'),
197
# path('<int:year>/<int:month>/<str:slug>/', PostDetailView.as_view(), name='post-detail'),
198
# path('<str:category>/<str:slug>/', PostDetailView.as_view(), name='post-detail'),
199
# path('<str:slug>/', PostDetailView.as_view(), name='post-detail'),
200
path('author/<str:username>/', AuthorEntriesView.as_view(), name='posts-author'),
201
path('category/<str:category>/', CategoryEntriesView.as_view(), name='posts-category'),
202
path('tag/<slug:tag>/', TaggedListView.as_view(), name='posts-tagged'),
203
path('archive/<int:year>/', PostArchiveView.as_view(), name='posts-archive-year'),
204
path('archive/<int:year>/<int:month>/', PostArchiveView.as_view(), name='posts-archive-month'),
205
path('archive/<int:year>/<int:month>/<int:day>/', PostArchiveView.as_view(), name='posts-archive-day'),
206
]
207
```
208
209
## View Usage Examples
210
211
```python
212
# Using views in URL configuration
213
from django.urls import path, include
214
from djangocms_blog.views import (
215
PostDetailView, PostListView, PostArchiveView,
216
TaggedListView, AuthorEntriesView, CategoryEntriesView
217
)
218
219
# Custom URL patterns
220
urlpatterns = [
221
path('blog/', include('djangocms_blog.urls', namespace='djangocms_blog')),
222
223
# Custom view usage
224
path('custom-posts/', PostListView.as_view(template_name='custom/post_list.html'), name='custom-posts'),
225
path('custom-author/<str:username>/', AuthorEntriesView.as_view(paginate_by=5), name='custom-author'),
226
]
227
228
# Custom view subclassing
229
from djangocms_blog.views import PostDetailView
230
from django.shortcuts import get_object_or_404
231
from myapp.models import CustomModel
232
233
class CustomPostDetailView(PostDetailView):
234
template_name = 'custom/post_detail.html'
235
236
def get_context_data(self, **kwargs):
237
context = super().get_context_data(**kwargs)
238
context['custom_data'] = CustomModel.objects.all()
239
return context
240
241
# Accessing view context in templates
242
# In post_detail.html template:
243
# {{ post.title }}
244
# {{ post.abstract|safe }}
245
# {{ post.get_absolute_url }}
246
# {% for category in post.categories.all %}{{ category.name }}{% endfor %}
247
# {% for tag in post.tags.all %}{{ tag.name }}{% endfor %}
248
249
# Custom queryset filtering
250
class FeaturedPostListView(PostListView):
251
def get_queryset(self):
252
return super().get_queryset().filter(featured=True)
253
254
# Adding custom context
255
class EnhancedPostDetailView(PostDetailView):
256
def get_context_data(self, **kwargs):
257
context = super().get_context_data(**kwargs)
258
post = self.get_object()
259
260
# Add related posts
261
context['related_posts'] = Post.objects.published().filter(
262
categories__in=post.categories.all()
263
).exclude(pk=post.pk)[:3]
264
265
# Add author's other posts
266
context['author_posts'] = Post.objects.published().filter(
267
author=post.author
268
).exclude(pk=post.pk)[:5]
269
270
return context
271
```