django的model.py admin.py views.py 中 的可循环遍历的 精简案例
使用循环来写models.py中的模型
使用循环来写admin.py中的定义后台栏目
使用循环来写api
如下面这个图中,推荐多个商品,字段变量是有逻辑的变换的
它的api的接口内容为:
{
"articles": [
{
"title_cn": "测试文章1【标题】",
"title_en": null,
"summary_cn": "文章概括中文",
"summary_en": "",
"content_cn": "文章富文本--中文:",
"content_en": "",
"product_1": true,
"product_1_title_cn": "有推荐商品1",
"product_1_title_en": null,
"product_1_summary_cn": "有推荐商品1的商品大致概括",
"product_1_summary_en": "",
"product_1_link_cn": null,
"product_1_link_en": null,
"image_1": null,
"tag_choice_1": "circle_image",
"product_2": false,
"product_2_title_cn": "有推荐商品2",
"product_2_title_en": null,
"product_2_summary_cn": "",
"product_2_summary_en": "",
"product_2_link_cn": null,
"product_2_link_en": null,
"image_2": null,
"tag_choice_2": "no_image",
"product_3": false,
"product_3_title_cn": null,
"product_3_title_en": null,
"product_3_summary_cn": "",
"product_3_summary_en": "",
"product_3_link_cn": null,
"product_3_link_en": null,
"image_3": null,
"tag_choice_3": "no_image",
"product_4": false,
"product_4_title_cn": null,
"product_4_title_en": null,
"product_4_summary_cn": "",
"product_4_summary_en": "",
"product_4_link_cn": null,
"product_4_link_en": null,
"image_4": null,
"tag_choice_4": "no_image",
"product_5": false,
"product_5_title_cn": null,
"product_5_title_en": null,
"product_5_summary_cn": "",
"product_5_summary_en": "",
"product_5_link_cn": null,
"product_5_link_en": null,
"image_5": null,
"tag_choice_5": "no_image",
"created_at": "2024-12-17T17:14:43.173Z",
"updated_at": "2024-12-17T17:14:43.173Z",
"change_count": 0,
"modification_times": []
}
]
}
使用循环来写models.py中的模型
这时,models.py中的可以配置为
from django.db import models
from django.utils import timezone
import json
class Article(models.Model):
# 图片形状的选项
NO_IMAGE = 'no_image'
CIRCLE_IMAGE = 'circle_image'
SQUARE_IMAGE = 'square_image'
TRIANGLE_IMAGE = 'triangle_image'
HEXAGON_IMAGE = 'hexagon_image'
IMAGE_TAG_CHOICES = [
(NO_IMAGE, '无图片'), # 无图片
(CIRCLE_IMAGE, '圆形图片'), # 圆形图片
(SQUARE_IMAGE, '方形图片'), # 方形图片
(TRIANGLE_IMAGE, '三角形图片'), # 三角形图片
(HEXAGON_IMAGE, '六边形图片'), # 六边形图片
]
# 标题字段
title_cn = models.CharField(max_length=255, verbose_name='文章中文标题')
title_en = models.CharField(max_length=255, blank=True, null=True, verbose_name='文章英文标题')
# 文章概括字段
summary_cn = models.TextField(verbose_name='文章概括中文')
summary_en = models.TextField(blank=True, null=True, verbose_name='文章概括英文')
# 内容字段
content_cn = models.TextField(verbose_name='文章富文本--中文')
content_en = models.TextField(blank=True, null=True, verbose_name='文章富文本--英文')
## 动态生成推荐商品和图片字段 Recommended Products (Repeat 5 times)
for i in range(1, 6):
locals()[f'product_{i}'] = models.BooleanField(default=False, verbose_name=f'推荐商品{i}【打勾后将会在主页列表中显示推荐】')
locals()[f'product_{i}_title_cn'] = models.CharField(max_length=255, blank=True, null=True, verbose_name=f'推荐商品{i}标题--中文')
locals()[f'product_{i}_title_en'] = models.CharField(max_length=255, blank=True, null=True, verbose_name=f'推荐商品{i}标题--英文')
locals()[f'product_{i}_summary_cn'] = models.TextField(blank=True, null=True, verbose_name=f'推荐商品{i}商品大致概括--中文')
locals()[f'product_{i}_summary_en'] = models.TextField(blank=True, null=True, verbose_name=f'推荐商品{i}商品大致概括--英文')
locals()[f'product_{i}_link_cn'] = models.URLField(blank=True, null=True, verbose_name=f'推荐商品{i}的链接--中文')
locals()[f'product_{i}_link_en'] = models.URLField(blank=True, null=True, verbose_name=f'推荐商品{i}的链接--英文')
# 图片字段和对应的标签选择字段
# locals()[f'image_{i}'] = models.ImageField(upload_to='images/', verbose_name=f'图片{i}路径')
# 使图片字段可为空
locals()[f'image_{i}'] = models.ImageField(
upload_to='images/',
verbose_name=f'图片{i}路径',
null=True, # 允许数据库中此字段为null
blank=True # 允许表单中此字段为空
)
# 商品图片形状
locals()[f'tag_choice_{i}'] = models.CharField(
max_length=20,
choices=IMAGE_TAG_CHOICES,
default=NO_IMAGE,
verbose_name=f'图片{i}标签选择'
)
# # 时间戳字段 Timestamps
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='最后修改时间')
change_count = models.PositiveIntegerField(default=0, verbose_name='更改次数')
# 修改时间(存储为JSON列表) Modification Times (stored as a JSON list)
modification_times = models.TextField(default='[]', verbose_name='修改时间')
class Meta:
verbose_name = '文章'
verbose_name_plural = '文章'
def __str__(self):
return self.title_cn
def save(self, *args, **kwargs):
if self.pk:
self.change_count += 1
mod_times = json.loads(self.modification_times)
mod_times.append(timezone.now().isoformat())
self.modification_times = json.dumps(mod_times)
super().save(*args, **kwargs)
def get_modification_times(self):
return json.loads(self.modification_times)
使用循环来写admin.py中的定义后台栏目
from django.contrib import admin
from django.utils.html import format_html
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title_cn', 'title_en', 'summary_cn', 'summary_en', 'recommended_products_count', 'created_at', 'updated_at', 'change_count')
search_fields = ('title_cn', 'title_en')
# Define fieldsets to organize form layout
fieldsets = (
('标题', {
'fields': (('title_cn', 'title_en'),)
}),
('概括', {
'fields': (('summary_cn', 'summary_en'),)
}),
('内容', {
'fields': (('content_cn', 'content_en'),)
}),
)
# Dynamically add fieldsets for recommended products
for i in range(1, 6):
fieldsets += (
(f'推荐商品{i}', {
'fields': (
f'product_{i}', f'product_{i}_title_cn', f'product_{i}_title_en',
f'product_{i}_summary_cn', f'product_{i}_summary_en',
f'product_{i}_link_cn', f'product_{i}_link_en',
f'image_{i}', f'tag_choice_{i}'
)
}),
)
readonly_fields = ('created_at', 'updated_at', 'change_count', 'modification_times')
def recommended_products_count(self, obj):
count = sum([getattr(obj, f'product_{i}') for i in range(1, 6)])
if count:
return format_html('<span>✔</span> {}', count)
else:
return format_html('<span>✖</span> {}', count)
recommended_products_count.short_description = '推荐商品数量'
admin.site.register(Article, ArticleAdmin)
使用循环来写api
views.py
from django.shortcuts import render
from django.core.paginator import Paginator
from .models import Article
from django.http import JsonResponse
def latest_articles_json(request):
articles = Article.objects.all().order_by('-created_at')[:10]
articles_list = []
for article in articles:
article_data = {
'title_cn': article.title_cn,
'title_en': article.title_en,
'summary_cn': article.summary_cn,
'summary_en': article.summary_en,
'content_cn': article.content_cn,
'content_en': article.content_en,
'created_at': article.created_at,
'updated_at': article.updated_at,
'change_count': article.change_count,
'modification_times': article.get_modification_times(),
}
# Add product and image details
for i in range(1, 6):
article_data.update({
f'product_{i}': getattr(article, f'product_{i}'),
f'product_{i}_title_cn': getattr(article, f'product_{i}_title_cn'),
f'product_{i}_title_en': getattr(article, f'product_{i}_title_en'),
f'product_{i}_summary_cn': getattr(article, f'product_{i}_summary_cn'),
f'product_{i}_summary_en': getattr(article, f'product_{i}_summary_en'),
f'product_{i}_link_cn': getattr(article, f'product_{i}_link_cn'),
f'product_{i}_link_en': getattr(article, f'product_{i}_link_en'),
f'image_{i}': getattr(article, f'image_{i}').url if getattr(article, f'image_{i}') else None,
f'tag_choice_{i}': getattr(article, f'tag_choice_{i}'),
})
articles_list.append(article_data)
return JsonResponse({'articles': articles_list})