django的model.py admin.py views.py 中 的可循环遍历的 精简案例

使用循环来写models.py中的模型

使用循环来写admin.py中的定义后台栏目

使用循环来写api

如下面这个图中,推荐多个商品,字段变量是有逻辑的变换的

它的api的接口内容为:

json 复制代码
{
    "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中的可以配置为

python 复制代码
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中的定义后台栏目

python 复制代码
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

python 复制代码
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})
相关推荐
阿巴斯甜3 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker3 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95274 小时前
Andorid Google 登录接入文档
android
黄林晴6 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab18 小时前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿21 小时前
Android MediaPlayer 笔记
android
Jony_21 小时前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android