You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Django利用URL id实现Base62编码的URL短链接服务

修复并完善短链接服务代码

1. 先修复URLGenerator的已知Bug

你的URLGenerator类缺少math模块导入,且_true_chr方法最后抛出异常时直接使用BASE未绑定实例,先修正这两处问题:

import math

class URLGenerator:
    BASE = 62
    UPPERCASE_OFFSET = 55
    LOWERCASE_OFFSET = 61
    DIGIT_OFFSET = 48

    def generate_unique_key(self, integer):
        """
        Turn an integer [integer] into a base [BASE] number
        in string representation
        """
        if integer == 0:
            return '0'
        string = ""
        remainder: int = 0
        while integer > 0:
            remainder = integer % self.BASE
            string = self._true_chr(remainder) + string
            integer = int(integer / self.BASE)
        return string

    def get_id(self, key):
        """
        Turn the base [BASE] number [key] into an integer
        """
        int_sum = 0
        reversed_key = key[::-1]
        for idx, char in enumerate(reversed_key):
            int_sum += self._true_ord(char) * int(math.pow(self.BASE, idx))
        return int_sum

    def _true_ord(self, char):
        """
        Turns a digit [char] in character representation
        from the number system with base [BASE] into an integer.
        """
        if char.isdigit():
            return ord(char) - self.DIGIT_OFFSET
        elif 'A' <= char <= 'Z':
            return ord(char) - self.UPPERCASE_OFFSET
        elif 'a' <= char <= 'z':
            return ord(char) - self.LOWERCASE_OFFSET
        else:
            raise ValueError("%s is not a valid character" % char)

    def _true_chr(self, integer):
        """
        Turns an integer [integer] into digit in base [BASE]
        as a character representation.
        """
        if integer < 10:
            return chr(integer + self.DIGIT_OFFSET)
        elif 10 <= integer <= 35:
            return chr(integer + self.UPPERCASE_OFFSET)
        elif 36 <= integer < 62:
            return chr(integer + self.LOWERCASE_OFFSET)
        else:
            raise ValueError(
                "%d is not a valid integer in the range of base %d" % (integer, self.BASE))

2. 完善Url模型

你原来的Url模型缺少原始长链接字段,且save方法需要补充短码生成逻辑:

from django.db import models

class Url(models.Model):
    url_id = models.AutoField(primary_key=True)
    original_url = models.URLField(verbose_name="原始长链接", max_length=500)
    short_code = models.CharField(verbose_name="短链编码", max_length=10, unique=True, blank=True)
    
    def save(self, *args, **kwargs):
        # 首次保存先调用父类方法生成自增ID
        if not self.pk:
            super().save(*args, **kwargs)
            # 基于自增ID生成短码
            generator = URLGenerator()
            self.short_code = generator.generate_unique_key(self.url_id)
            # 移除强制插入参数,避免二次保存报错
            kwargs.pop('force_insert', None)
        super().save(*args, **kwargs)

可选优化:如果需要避免同一个长链接重复生成短链,可以在创建数据前先查询original_url是否已存在,存在则直接返回已有短链。

3. 编写views.py业务逻辑

提供两个核心接口:POST提交长链接生成短链、GET访问短码跳转到原始链接

from django.shortcuts import get_object_or_404, redirect
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from .models import Url

# 生成短链的POST接口
@require_http_methods(["POST"])
def generate_short_url(request):
    original_url = request.POST.get("original_url")
    if not original_url:
        return JsonResponse({"code": 400, "msg": "缺少原始链接参数"}, status=400)
    # 存入数据库自动生成短码
    url_obj = Url.objects.create(original_url=original_url)
    # 拼接完整短链返回
    short_url = f"{request.scheme}://{request.get_host()}/{url_obj.short_code}"
    return JsonResponse({"code": 200, "short_url": short_url, "original_url": original_url})

# 短链跳转接口
@require_http_methods(["GET"])
def redirect_to_original(request, short_code):
    url_obj = get_object_or_404(Url, short_code=short_code)
    # 302临时跳转,需要统计点击量可在此处新增计数逻辑
    return redirect(url_obj.original_url)

如果不想存储short_code字段,可以注释掉模型中的对应字段,跳转时先通过URLGenerator().get_id(short_code)解码拿到url_id再查询即可。

4. 配置urls.py路由

在项目/应用的路由文件中添加对应规则:

from django.urls import path
from . import views

urlpatterns = [
    path("generate/", views.generate_short_url, name="generate_short"),
    path("<str:short_code>/", views.redirect_to_original, name="redirect_original"),
]

效果验证

可以用curl工具发送测试请求:

curl -X POST -d "original_url=https://www.baidu.com" http://127.0.0.1:8000/generate/

请求成功会返回生成好的短链,直接访问短链即可跳转到对应原始链接。

内容的提问来源于stack exchange,提问作者Aylin Naebzadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 16:09:03