Django基础教程(七十八)Django友情链接组件之设计友情链接数据模型:如何给你的Django网站,装上一个“社交牛X症”的友情链接组件!

一、为啥要大动干戈设计数据模型?(思想工作要先做通)

很多新手可能会想:“不就几个链接吗?我在基模板(base.html)里写死几个<a>标签不就完事了?”

打住!此想法危险!

手动写死的友链,堪称“互联网化石”,存在三大致命伤:

  1. 维护成本高:每次增、删、改一个友链,你都得吭哧吭哧地去改代码、通过Git部署。朋友站点的URL要是变了,你得等他通知你,你再手动去改……这流程,想想都头大。
  2. 毫无灵活性:想给友链分个类(比如“技术大佬”、“生活博主”)?想按某种顺序排序?想只在前端显示一部分?手动写死的情况下,这些需求基本等于“推倒重来”。
  3. 不利于管理:非技术人员(比如你的运营小伙伴)根本没法参与管理,你成了唯一的“链长”。

所以,我们的目标很明确:把友情链接“数据化”,让它变成一个可以在后台动态管理、在前端灵活展示的“活”组件。

二、开干!设计一个“德智体美劳”全面的友链模型

现在,请出我们今天的主角——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的思维去解构和设计时,竟能演化出如此强大和灵活的系统。

我们回顾一下核心步骤:

  1. 精准建模:从name, url核心,扩展到logo, description, category等丰富字段。
  2. 强化后台:通过Django Admin配置,打造一个零代码、高效率的管理界面。
  3. 灵动前端:通过视图查询和模板渲染,将数据以多种形式(列表、网格)优雅地呈现给用户。

从此以后,管理友链不再是你的专属工作,你可以把后台账号丢给任何小伙伴,他们都能轻松搞定。你的网站也因为有了这个动态、美观的“朋友圈”,而变得更加生动和互联。

还等什么?赶紧给你的Django项目,装上这个“社交牛X症”组件,让它去广交天下豪杰吧!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值