update. 完成分类显示与详情页显示效果
This commit is contained in:
+5
-5
@@ -11,11 +11,11 @@ from .models import NewsSection, News
|
||||
# --- 1. 板块管理配置 ---
|
||||
@admin.register(NewsSection)
|
||||
class NewsSectionAdmin(ImportExportModelAdmin):
|
||||
list_display = ('name', 'code', 'order', 'enabled') # 列表显示的字段
|
||||
list_editable = ('order', 'enabled') # 允许直接在列表页修改排序和状态
|
||||
search_fields = ('name', 'code') # 搜索框
|
||||
prepopulated_fields = {'code': ('name',)} # 输入名称时自动生成 Slug
|
||||
ordering = ('order', 'name') # 默认排序
|
||||
list_display = ('title', 'code', 'order', 'visible') # 列表显示的字段
|
||||
list_editable = ('order', 'visible') # 允许直接在列表页修改排序和状态
|
||||
search_fields = ('title', 'code') # 搜索框
|
||||
prepopulated_fields = {'code': ('title',)} # 输入名称时自动生成 Slug
|
||||
ordering = ('order', 'title') # 默认排序
|
||||
|
||||
|
||||
# --- 2. 文章管理配置 ---
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 6.0.3 on 2026-04-01 09:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('news', '0002_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='newssection',
|
||||
options={'ordering': ('order', 'title'), 'verbose_name': '新闻模块', 'verbose_name_plural': '新闻模块'},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='newssection',
|
||||
old_name='name',
|
||||
new_name='title',
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='newssection',
|
||||
old_name='enabled',
|
||||
new_name='visible',
|
||||
),
|
||||
]
|
||||
+4
-4
@@ -7,18 +7,18 @@ from users.models import User
|
||||
|
||||
# Create your models here.
|
||||
class NewsSection(BaseEntity):
|
||||
name = models.CharField('模块名称', max_length=100, unique=True)
|
||||
title = models.CharField('模块名称', max_length=100, unique=True)
|
||||
code = models.SlugField('唯一标识', max_length=50, unique=True, help_text='用于模板或URL识别,建议英文')
|
||||
order = models.PositiveSmallIntegerField('排序权重', default=0)
|
||||
enabled = models.BooleanField('启用状态', default=True)
|
||||
visible = models.BooleanField('启用状态', default=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '新闻模块'
|
||||
verbose_name_plural = '新闻模块'
|
||||
ordering = ('order', 'name')
|
||||
ordering = ('order', 'title')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return self.title
|
||||
|
||||
|
||||
class News(BaseEntity):
|
||||
|
||||
+53
-21
@@ -19,49 +19,81 @@ fake = Faker('zh_CN')
|
||||
|
||||
|
||||
def seed_news(count=20):
|
||||
print(f"🚀 开始生成 {count} 条新闻数据...")
|
||||
print(f"🚀 开始生成 {count} 条富文本新闻数据...")
|
||||
|
||||
# --- 1. 获取关联数据 ---
|
||||
# 获取所有板块
|
||||
sections = list(NewsSection.objects.all())
|
||||
# 获取所有用户
|
||||
users = list(User.objects.all())
|
||||
|
||||
# 检查基础数据是否存在
|
||||
if not sections:
|
||||
print("❌ 错误:数据库中没有找到任何板块 (NewsSection)!请先添加板块。")
|
||||
print("❌ 错误:数据库中没有找到任何板块 (NewsSection)!")
|
||||
return
|
||||
if not users:
|
||||
print("⚠️ 警告:数据库中没有用户 (User),作者字段将设为空。")
|
||||
|
||||
# --- 2. 生成数据 ---
|
||||
created_count = 0
|
||||
|
||||
for i in range(count):
|
||||
# 随机选择一个板块
|
||||
section = random.choice(sections)
|
||||
# 随机选择一个作者 (如果有用户)
|
||||
author = random.choice(users) if users else None
|
||||
|
||||
# 生成富文本内容 (模拟 CKEditor 输出的 HTML)
|
||||
# paragrahs 生成多段文本,join 拼接
|
||||
paragraphs = fake.paragraphs(nb=random.randint(3, 6))
|
||||
content_html = "\n".join([f"<p>{p}</p>" for p in paragraphs])
|
||||
# --- 2. 构建丰富的 HTML 内容 ---
|
||||
html_parts = []
|
||||
|
||||
# 创建新闻对象
|
||||
# A. 开头:一段引言或摘要
|
||||
if random.random() > 0.5:
|
||||
html_parts.append(f"<p><strong>【摘要】</strong> {fake.sentence(nb_words=10)}</p>")
|
||||
|
||||
# B. 正文第一段
|
||||
html_parts.append(f"<p>{fake.paragraph(nb_sentences=4)}</p>")
|
||||
|
||||
# C. 随机插入图片占位符 (模拟上传的封面或插图)
|
||||
# 使用 placehold.co 生成带文字的灰色占位图
|
||||
img_width = random.choice([600, 800])
|
||||
img_height = random.choice([300, 400])
|
||||
img_text = fake.words(nb=3, unique=True)
|
||||
html_parts.append(
|
||||
f'<div style="text-align: center; margin: 20px 0;"><img src="https://placehold.co/{img_width}x{img_height}/23418A/FFF?text={"+".join(img_text)}" style="max-width: 100%; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);"></div>')
|
||||
|
||||
# D. 正文中间段落
|
||||
html_parts.append(f"<p>{fake.paragraph(nb_sentences=5)}</p>")
|
||||
|
||||
# E. 随机插入引用块 (增加排版层次感)
|
||||
if random.random() > 0.6:
|
||||
quote = fake.sentence(nb_words=8)
|
||||
html_parts.append(
|
||||
f'<blockquote style="border-left: 5px solid #23418A; padding: 10px 20px; margin: 20px 0; background: #f8f9fa; color: #555;"><i>"{quote}"</i></blockquote>')
|
||||
|
||||
# F. 随机插入无序列表 (模拟要点陈述)
|
||||
if random.random() > 0.7:
|
||||
list_items = "".join([f"<li>{fake.sentence()}</li>" for _ in range(3)])
|
||||
html_parts.append(f"<ul style='margin: 20px 0; padding-left: 20px;'>{list_items}</ul>")
|
||||
|
||||
# G. 加粗和斜体混合段落
|
||||
p1 = fake.paragraph(nb_sentences=2)
|
||||
p2 = fake.paragraph(nb_sentences=2)
|
||||
html_parts.append(f"<p>{p1} <strong style='color: #23418A;'>{fake.words(nb=4, unique=True)}</strong> {p2}</p>")
|
||||
|
||||
# H. 结尾
|
||||
html_parts.append(f"<p>{fake.paragraph(nb_sentences=3)}</p>")
|
||||
|
||||
# 拼接最终 HTML
|
||||
content_html = "\n".join(html_parts)
|
||||
|
||||
# --- 3. 创建对象 ---
|
||||
news = News.objects.create(
|
||||
title=fake.sentence(nb_words=random.randint(4, 8))[:-1], # 生成标题并去掉末尾句号
|
||||
title=fake.sentence(nb_words=random.randint(4, 8))[:-1],
|
||||
section=section,
|
||||
author=author,
|
||||
content=content_html,
|
||||
is_published=True, # 默认已发布
|
||||
# 封面图留空,因为自动生成图片文件比较复杂,建议手动上传测试图
|
||||
is_published=True,
|
||||
# 可以在这里加上摘要字段,如果有的话
|
||||
# summary=fake.paragraph(nb_sentences=1)
|
||||
)
|
||||
|
||||
created_count += 1
|
||||
print(f" - [{section.name}] {news.title}")
|
||||
print(f" - [{section.title}] {news.title}")
|
||||
|
||||
print(f"✅ 成功生成 {created_count} 条新闻数据!")
|
||||
print(f"✅ 成功生成 {created_count} 条富文本新闻数据!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
seed_news(30)
|
||||
seed_news(120)
|
||||
|
||||
Reference in New Issue
Block a user