一、为啥要大动干戈设计数据模型?(思想工作要先做通)
很多新手可能会想:“不就几个链接吗?我在基模板(base.html)里写死几个<a>标签不就完事了?”
打住!此想法危险!
手动写死的友链,堪称“互联网化石”,存在三大致命伤:
- 维护成本高:每次增、删、改一个友链,你都得吭哧吭哧地去改代码、通过Git部署。朋友站点的URL要是变了,你得等他通知你,你再手动去改……这流程,想想都头大。
- 毫无灵活性:想给友链分个类(比如“技术大佬”、“生活博主”)?想按某种顺序排序?想只在前端显示一部分?手动写死的情况下,这些需求基本等于“推倒重来”。
- 不利于管理:非技术人员(比如你的运营小伙伴)根本没法参与管理,你成了唯一的“链长”。
所以,我们的目标很明确:把友情链接“数据化”,让它变成一个可以在后台动态管理、在前端灵活展示的“活”组件。
二、开干!设计一个“德智体美劳”全面的友链模型
现在,请出我们今天的主角——Link 模型。我们将在这个models.py文件里大展拳脚。
第一步:核心字段,一个都不能少
这些是一个友链最基本的“生存保障”。
from django.db import models
class Link(models.Model):
"""友情链接模型"""
# 1. 名字:你朋友站点的名字,比如“隔壁老王的编程乐园”
name = models.CharField('网站名称', max_length=20, unique=True)
# 2. 链接:朋友家的“门牌号”,必须能点过去
url = models.URLField('网址', max_length=100)
# 就这么简单?不,这只是一个开始!
看,现在我们已经有能力在数据库里记录友链了。但一个成熟的友链组件,绝不能如此“朴素”。
第二步:锦上添花,让友链“卷”起来
我们要让友链在视觉上和功能上更出彩。
from django.db import models
class Link(models.Model):
# ... 上面的基础字段 ...
# 3. 图标/Logo:一个漂亮的Logo能让友链区逼格飙升
# 我们允许它为空,不是所有网站都能轻松搞到Logo的
logo = models.URLField('网站Logo', max_length=200, blank=True, help_text='建议使用正方形的图片链接')
# 4. 描述:用一句话介绍你的朋友,比如“一个专注分享Python干货的博主”
description = models.CharField('网站描述', max_length=200, blank=True)
# 5. 排序:谁排第一谁排第二?咱得有个规矩
# 使用 PositiveIntegerField 确保是正整数,default=1 给个默认值
order = models.PositiveIntegerField('排序', default=1)
# 6. 是否展示:万一某个友链暂时“失联”,我们可以先隐藏,而不是删除
is_active = models.BooleanField('是否展示', default=True)
# 7. 创建时间:记录什么时候交的这个“朋友”
created_time = models.DateTimeField('创建时间', auto_now_add=True)
第三.步:高级玩法——给友链分个“圈子”
朋友也分很多种,有“酒肉朋友”,有“良师益友”。给友链分类,能让你的页面布局更清晰。
class Category(models.Model):
"""友情链接分类"""
name = models.CharField('分类名', max_length=10)
order = models.PositiveIntegerField('排序', default=1)
created_time = models.DateTimeField('创建时间', auto_now_add=True)
class Meta:
verbose_name = '友链分类'
verbose_name_plural = verbose_name # 避免在Admin后台显示成“Categorys”
def __str__(self):
return self.name
class Link(models.Model):
# ... 上面的所有字段 ...
# 8. 分类:一个分类下可以有多个友链,一个友链只属于一个分类(多对一关系)
category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.CASCADE, related_name='links')
# ... 其他字段 ...
第四步:模型的“内功心法”——Meta类
Django的Meta类是用来给模型本身加 buff 的。
class Link(models.Model):
# ... 所有字段 ...
class Meta:
verbose_name = '友情链接' # 在Admin后台显示的单数名称
verbose_name_plural = verbose_name # 复数名称,通常一样就行
ordering = ['order', '-created_time'] # 默认排序:先按order正序,再按创建时间倒序
def __str__(self):
return self.name # 在Admin后台,每个对象显示为它的名字
完整模型代码一览:
from django.db import models
class Category(models.Model):
name = models.CharField('分类名', max_length=10)
order = models.PositiveIntegerField('排序', default=1)
created_time = models.DateTimeField('创建时间', auto_now_add=True)
class Meta:
verbose_name = '友链分类'
verbose_name_plural = verbose_name
ordering = ['order', '-created_time']
def __str__(self):
return self.name
class Link(models.Model):
category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.CASCADE, related_name='links')
name = models.CharField('网站名称', max_length=20, unique=True)
url = models.URLField('网址', max_length=100)
logo = models.URLField('网站Logo', max_length=200, blank=True)
description = models.CharField('网站描述', max_length=200, blank=True)
order = models.PositiveIntegerField('排序', default=1)
is_active = models.BooleanField('是否展示', default=True)
created_time = models.DateTimeField('创建时间', auto_now_add=True)
class Meta:
verbose_name = '友情链接'
verbose_name_plural = verbose_name
ordering = ['order', '-created_time']
def __str__(self):
return self.name
三、光有模型可不行,让它能在后台“蹦跶”起来
模型是骨架,Admin后台是血肉。我们需要在admin.py中注册它们,并做一些优化。
from django.contrib import admin
from .models import Category, Link
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'order', 'created_time') # 列表页显示的字段
list_editable = ('order',) # 可以直接在列表页修改排序
search_fields = ('name',) # 添加搜索框
@admin.register(Link)
class LinkAdmin(admin.ModelAdmin):
list_display = ('name', 'category', 'url', 'order', 'is_active', 'created_time')
list_editable = ('category', 'url', 'order', 'is_active') # 方便批量操作
list_filter = ('category', 'is_active', 'created_time') # 添加过滤器
search_fields = ('name', 'description') # 按名称和描述搜索
# 定义一个方法,用于在后台显示Logo预览(如果需要的话)
# readonly_fields = ('logo_preview',) # 如果需要预览可以取消注释并定义方法
# 注意:记得执行 python manage.py makemigrations 和 python manage.py migrate 来创建数据库表!
现在,你的Django Admin后台就有了一个功能强大的友情链接管理中心!你可以像操作Excel表格一样,轻松增删改查、筛选、排序所有友链。
四、终极奥义:把数据“秀”到前端页面上
后台数据准备好了,最后一步就是让用户在网站上看到它们。
1. 在视图(views.py)中获取数据
假设我们在一个叫 home 的视图里,想要把友链传递到首页模板。
from django.shortcuts import render
from .models import Category
def home(request):
# 获取所有有效的、并按我们设定顺序排好的分类,并预取关联的、有效的友链
link_categories = Category.objects.prefetch_related(
'links' # 使用我们在ForeignKey里定义的 related_name='links'
).filter(links__is_active=True).distinct().order_by('order')
context = {
'link_categories': link_categories,
}
return render(request, 'home.html', context)
2. 在模板(home.html)中循环渲染
这里我们展示两种常见的友链展示风格。
风格一:极简文字列表(适合侧边栏)
<!-- 假设这是你的侧边栏 -->
<aside class="widget friend-links">
<h3>我的朋友们</h3>
{% for category in link_categories %}
<h4>{{ category.name }}</h4>
<ul>
{% for link in category.links.all %}
{% if link.is_active %} <!-- 双重保险 -->
<li>
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer" title="{{ link.description }}">
{{ link.name }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</aside>
风格二:豪华Logo网格(适合独立友链页)
<!-- 一个专门的友情链接页面 -->
<div class="friend-links-page">
<h1>友情链接</h1>
{% for category in link_categories %}
<section class="link-category">
<h2>{{ category.name }}</h2>
<div class="link-grid">
{% for link in category.links.all %}
{% if link.is_active %}
<div class="link-item">
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer" class="link-logo">
<!-- 如果有Logo就显示,没有就显示默认图片或名字首字母 -->
{% if link.logo %}
<img src="{{ link.logo }}" alt="{{ link.name }} Logo" loading="lazy">
{% else %}
<div class="no-logo">{{ link.name.0 }}</div> <!-- 显示名字首字母 -->
{% endif %}
</a>
<div class="link-info">
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer" class="link-name">
{{ link.name }}
</a>
<p class="link-description">{{ link.description }}</p>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</section>
{% endfor %}
</div>
别忘了加点CSS魔法,让它更好看!
/* 简单的网格布局 */
.link-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
margin-top: 15px;
}
.link-item {
border: 1px solid #eee;
border-radius: 8px;
padding: 15px;
text-align: center;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.link-item:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.link-logo img,
.link-logo .no-logo {
width: 50px;
height: 50px;
border-radius: 50%;
margin: 0 auto 10px;
display: block;
line-height: 50px;
background-color: #f5f5f5;
color: #666;
font-weight: bold;
}
.link-name {
font-weight: bold;
color: #333;
text-decoration: none;
}
.link-description {
font-size: 0.9em;
color: #666;
margin-top: 5px;
}
五、总结与升华
看,一个看似简单的“友情链接”,当我们用Django的思维去解构和设计时,竟能演化出如此强大和灵活的系统。
我们回顾一下核心步骤:
- 精准建模:从
name,url核心,扩展到logo,description,category等丰富字段。 - 强化后台:通过Django Admin配置,打造一个零代码、高效率的管理界面。
- 灵动前端:通过视图查询和模板渲染,将数据以多种形式(列表、网格)优雅地呈现给用户。
从此以后,管理友链不再是你的专属工作,你可以把后台账号丢给任何小伙伴,他们都能轻松搞定。你的网站也因为有了这个动态、美观的“朋友圈”,而变得更加生动和互联。
还等什么?赶紧给你的Django项目,装上这个“社交牛X症”组件,让它去广交天下豪杰吧!
359

被折叠的 条评论
为什么被折叠?



