如何用React、Django REST框架和SQLite数据库创建一个URL缩短器

280 阅读8分钟

如何用React、Django REST框架和SQLite数据库创建一个URL缩短器

在这篇文章中,我们将学习如何创建一个自定义的URL(统一资源定位器)缩短器服务。这个URL缩短器将接收一个长的URL,并提供一个相应的短的URL,适合在社交媒体上发布并与朋友分享。

缩短器服务将由三部分组成。

  • 用于与客户互动的前端(我们将使用React.js构建前端)。
  • 后台用于创建服务器,并提供API路由(我们将使用Django REST框架构建后台)。
  • 用于存储数据的数据库(我们将使用SQLite数据库)。

用户将复制一个网址,粘贴在所提供的输入字段中,然后点击shorten 按钮。网址将使用Fetch API 发送给后端,后端将应用一个程序来提供一个等同的6位数短网址。

对等的URL意味着短URL将把用户重定向到与长URL相同的页面。

前提条件

要想跟上,读者应该具备以下条件。

  • 了解Django REST框架。
  • 了解Django REST框架中的序列化器。
  • 对React钩子的基本了解。
  • 对Fetch API的理解。
  • 计算机上安装有Python和Node.js。
  • 一个浏览器(最好是谷歌浏览器)。
  • 一个代码编辑器(最好是VS Code)。

目标

在本文结束时,读者应该能够。

  • 创建一个自定义的URL缩短器。
  • 使用React和Django工作。
  • 使用Django从数据库中获取数据,并将其显示在React网页上。

设置后端和暴露API路由

创建一个名为react-drf-shortener 的文件夹并导航到其中。

首先,为Django后端创建一个虚拟环境。

在终端运行下面的命令来创建虚拟环境,激活它,并在其中安装Django。

python -m venv shortener-env

.\shortener-env\Scripts\activate

python -m pip install Django

Django安装成功后,在同一目录下运行以下命令,创建一个名为urlshortener 的Django项目,并在VS Code中打开该文件夹。

django-admin startproject urlshortener

在代码编辑器中打开集成终端,确保虚拟环境仍处于活动状态。如果没有,运行下面的命令来激活它。

cd ..

.\shortener-env\Scripts\activate

cd urlshortener

上述命令将我们的活动目录改为根目录,激活虚拟环境,然后导航到urlshortener 文件夹。

运行下面的代码以确保服务器正常工作。

python manage.py runserver

如果服务器工作完美,这将在http://127.0.0.1:8000/ ,打开一个开发服务器。

现在,服务器工作得很好,我们将创建一个新的应用程序来处理来自前端的所有API请求,如下图所示。

django-admin startapp api

接下来,运行下面的命令来安装我们将需要的所有软件包/依赖项。

pip install djangorestframework

python -m pip install django-cors-headers

上面的代码做了以下工作。

  • pip install djangorestframework 将安装Django Rest Framework(DRF)。DRF允许我们使用Django创建一个API。
  • python -m pip install django-cors-headers 将安装CORS,以允许Django后端与React前端进行通信。

注册API和已安装的包

打开settings.py 文件,修改其内容,如下所示。

对于INSTALLED_APPS 部分。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'api.apps.ApiConfig', #registers our api app

    'rest_framework',

    'corsheaders'
]

INSTALLED_APPS 部分保存了在这个特定Django实例中激活的所有Django应用程序的名称。

在这一节中,我们添加。

  • api.apps.ApiConfig - 这注册了我们之前创建的API应用程序。
  • rest_framework 和 - 这注册了我们用 安装的模块。corsheaders pip

对于MIDDLEWARE 部分。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',

     "corsheaders.middleware.CorsMiddleware",

    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

MIDDLEWARE 部分是一个进入Django的请求/响应处理的钩子框架。它是一个 "插件 "系统,用于全面改变Django的输入或输出。

在上面的代码中,我们添加了corsheaders.middleware.CorsMiddleware 来监听响应。

将以下代码追加到settings.py 文件中。

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:3000",
]

上面的代码指定了与Django后端通信的客户端。

打开urlshortener 文件夹中的urls.py 文件,如下图所示进行修改,将所有的请求路由到我们之前创建的api 应用程序。

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('api.urls')),
]

在API应用程序上工作

创建模型

打开api 文件夹中的models.py 文件,并按下图所示进行修改。

from django.db import models

class urlShortener(models.Model):
    longurl = models.CharField(max_length=255)
    shorturl = models.CharField(max_length=10)

    def __str__(self):
        return self.shorturl

上面的代码将在数据库中创建一个有两个字段的表。

  • longurl - 存储用户从前端提交的长URL。
  • shorturl - 存储服务器生成的长网址的短网址等值。

运行下面的命令,将对模型的修改传播到数据库模式中。

python manage.py makemigrations

python manage.py migrate

创建序列化器

app 文件夹中,创建一个serializers.py 文件,并按下图所示修改它。

from rest_framework.serializers import ModelSerializer
from .models import urlShortener

class urlShortenerSerializer(ModelSerializer):
    class Meta:
        model = urlShortener
        fields = '__all__

上面的代码将序列化urlShortener 模型中的所有字段。

在视图上工作

视图是Python中的一个函数,它接收来自客户端的请求并返回一个响应。视图包含了所有返回响应的必要逻辑。

打开views.py 文件,并按下图所示进行修改。

from django.shortcuts import redirect
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import urlShortener
from .serializers import urlShortenerSerializer

import random

@api_view(['POST'])
def makeshorturl(request):
    data = request.data
    s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!*^$-_"
    shorturl = ("".join(random.sample(s, 6)))
    urlShortener.objects.create(
        longurl=data['longurl'],
        shorturl=shorturl
    )
    longurl = data['longurl']
    shorturl = "http://localhost:8000/"+shorturl
    return Response({'longurl': longurl, 'shorturl': shorturl})


def redirectUrl(request, shorturl):
    try:
        obj = urlShortener.objects.get(shorturl=shorturl)
    except urlShortener.DoesNotExist:
        obj = None

    if obj is not None:
        return redirect(obj.longurl)

makeshorturl 视图中,我们使用Django REST框架提供的@api_view 装饰器,只限制POST请求到视图。视图接收前端数据,并从一串预定义的字母、数字和符号中创建一个shorturl

shorturl 的长度为六个字符。然后,longurlshorturl 对象被存储在数据库中,并将Response ,连同长URL和生成的短URL返回给用户。

redirectUrl 视图接纳了requestshorturlshorturl 参数将在urls.py 文件中指定。这个视图使用一个try except 语句从数据库中检索一个对象,其中提供的shorturl 等于数据库中的shorturl。

如果找到对象,用户会被重定向到从数据库中检索的对象中的longurl

为了创建shorturl ,我们首先创建一个变量s ,该变量有一组预定义的字符。

然后我们使用random.sample() 方法来创建,从变量s 中随机抽取六个字符。这将返回一个Python列表。最后,我们使用join() 方法来连接列表中的所有项目,形成shorturl

在 urls 上工作

打开urls.py 文件,按下面的方式修改。

from django.urls import path
from . import views

urlpatterns = [
    path('shorten/', views.makeshorturl),
    path('<str:shorturl>', views.redirectUrl)
]

上述代码暴露了前端要访问的API端点。

要运行服务器,请运行以下命令。

python manage.py runserver

设置前端

使用命令提示符导航到react-drf-shortener 文件夹,并运行以下命令。

npx create-react-app shortener-frontend

code shortener-frontend

这将创建一个react应用并在VS Code中打开它。

打开App.js 文件,用下面提供的代码修改它。

import { useState } from "react";

function App() {
    const [longurl, setLongurl] = useState("");
    const [shorturl, setShorturl] = useState("");
    const [returnLongURL, setReturnLongURL] = useState("");

    const handleSubmit = (e) => {
        e.preventDefault();

        fetch("http://127.0.0.1:8000/shorten/", {
            method: "POST",
            body: JSON.stringify({ longurl: longurl }),
            headers: { "Content-Type": "application/json" },
        })
            .then((res) => res.json())
            .then((data) => {
                setShorturl(data.shorturl);
                setReturnLongURL(data.longurl);
                setLongurl("");
            });
    };

    return (
        <div style={{ textAlign: "center" }}>
            <input
                type="text"
                name="longurl"
                value={longurl}
                onChange={(e) => setLongurl(e.target.value)}
            />
            <button
                type="submit"
                onClick={(e) => handleSubmit(e)}
                disabled={!longurl}
            >
                shorten
            </button>

            <div>
                <p>Long URL: {returnLongURL}</p>
                <p
                    style={{ cursor: "pointer" }}
                    onClick={() => window.open(returnLongURL)}
                >
                    Short URL: {shorturl}
                </p>
            </div>
        </div>
    );
}

export default App;

我们在上面的代码中从react 中导入useState() 钩子。然后,我们设置了三个状态,解释如下。

  • longurl - 将用于跟踪用户提供的输入。
  • shorturl - 将用于保存服务器返回的短网址的值。
  • returnLongURL - 将用于保存服务器提供的长URL的值。

return 部分,有一个输入字段和一个按钮,当点击时调用handleSubmit() 函数。这个函数使用fetch API ,将longurl 发送给后端。fetch API 返回一个响应,并设置shorturlreturnLongURL 的值。

长的URL和短的URL会在浏览器上呈现。我们使用window.open() 方法,在点击短网址时,在新标签页上打开长网址。

要运行前端代码,在集成终端中输入以下命令并按回车键。

npm start

上述命令将打开一个本地开发服务器,在127.0.0.1:3000

测试缩短器服务

要测试该服务,打开浏览器并导航到127.0.0.1:3000 。确保服务器正在运行。

将长的URL粘贴到提供的输入字段中,然后点击shorten 按钮。一个短的URL将被呈现出来,在点击它时,它会重定向到与长URL相同的网页。

这意味着我们的缩短器服务正在工作。

工作应用的证明。 Working application

证明短URL重定向到与长URL相同的页面。 Redirected to same URL

结论

我们已经学会了如何使用React和Django实现一个简单的缩短器服务。然而,这个项目可以通过设计用户界面的风格和添加更多的功能而更上一层楼。

其中一个可能被添加的功能是计算一个链接被创建的次数。