Django AI 聊天机器人项目:基于 ChatGPT 的 Django REST API
本文档将介绍如何使用 Django 和 Django REST Framework 构建一个 AI 聊天机器人项目,并结合 OpenAI 的 GPT 模型提供代码解释服务。步骤包括创建 Django 项目、配置 API、与 OpenAI 集成,并最终提供一个可通过 REST API 调用的服务。
项目结构
drf_chatgpt/ # Django 项目目录
├── api/ # API 应用目录
├── src/ # Django 配置文件目录
├── manage.py # Django 管理工具
├── .env # 环境变量文件
├── requirements.txt # 项目依赖
步骤 1:创建虚拟环境
首先,创建一个虚拟环境来隔离项目的依赖:
python -m venv venv
激活虚拟环境:
- Windows:
venv\Scripts\activate
- Linux / MacOS:
source venv/bin/activate
步骤 2:安装依赖
安装 Django、Django REST Framework 和 OpenAI SDK:
pip install django djangorestframework openai
生成 requirements.txt
以便日后使用:
pip freeze > requirements.txt
步骤 3:创建 Django 项目
使用 django-admin
命令创建一个名为 src
的 Django 项目:
django-admin startproject src .
修改 src/settings.py
在 INSTALLED_APPS
中添加所需的应用:
INSTALLED_APPS = [
# external apps
'rest_framework',
'rest_framework.authtoken',
# internal apps
'api',
# default apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
步骤 4:创建数据库并运行开发服务器
-
创建数据库迁移并应用:
python manage.py migrate
-
创建超级用户以便访问 Django 管理后台:
python manage.py createsuperuser
-
启动开发服务器:
python manage.py runserver
步骤 5:获取 OpenAI API Key
使用环境变量来存储 OpenAI API 密钥。首先,创建一个 .env
文件并将 API 密钥添加到其中:
# .env 文件
OPENAI_APIKEY="sk-Wxxxxxxxx"
在 settings.py
中加载该变量:
import os
from dotenv import load_dotenv
load_dotenv()
APIKEY = os.getenv("OPENAI_APIKEY")
步骤 6:创建 API 应用
创建一个新的 Django 应用 api
:
python manage.py startapp api
设置 API 请求到 OpenAI 的工具函数
在 api/utils.py
中创建与 OpenAI API 的集成函数:
import openai
from django.conf import settings
openai.api_key = settings.APIKEY
def send_code_to_api(code):
try:
res = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": f"Tell me what language is this code written? {code}"},
{"role": "system", "content": "You are a helpful assistant that provides code explanations."},
{"role": "assistant", "content": "Sure! Please provide the code you want me to explain."}
],
)
return res["choices"][0]["message"]["content"]
except openai.error.APIError as e:
raise ValueError(f"OpenAI API returned an API Error: {e}")
except openai.error.APIConnectionError as e:
raise ValueError(f"Failed to connect to OpenAI API: {e}")
except openai.error.RateLimitError as e:
raise ValueError(f"OpenAI API request exceeded rate limit: {e}")
步骤 7:创建模型
在 api/models.py
中定义一个用于存储代码及其解释的模型:
from django.db import models
class CodeExplainer(models.Model):
_input = models.TextField()
_output = models.TextField()
class Meta:
db_table = "t_code_explainer"
创建并迁移模型:
python manage.py makemigrations api
python manage.py migrate api
步骤 8:配置 URL 和视图
- 在项目的
urls.py
中包含api.urls
:
# src/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('api.urls'))
]
- 在
api/urls.py
中定义 API 路由:
# api/urls.py
from django.urls import path
from api.views import UserView, TokenView, CodeExplainView
urlpatterns = [
path('users/', UserView.as_view(), name='users'),
path('tokens/', TokenView.as_view(), name='tokens'),
path('code-explain/', CodeExplainView.as_view(), name='code-explain')
]
- 在
api/views.py
中实现视图逻辑:
# api/views.py
from rest_framework import views, status
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import AllowAny
from api.serializers import CodeExplainSerializer, UserSerializer, TokenSerializer
from api.models import CodeExplainer
class CodeExplainView(views.APIView):
serializer_class = CodeExplainSerializer
authentication_classes = [TokenAuthentication]
def get(self, request, format=None):
qs = CodeExplainer.objects.all()
serializer = self.serializer_class(qs, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# 用户和 token 视图 (稍后定义)
class UserView(views.APIView):
serializer_class = UserSerializer
permission_classes = [AllowAny]
class TokenView(ObtainAuthToken):
serializer_class = TokenSerializer
步骤 9:实现序列化器
在 api/serializers.py
中编写模型序列化器:
# api/serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
from api.models import CodeExplainer
from api.utils import send_code_to_api
class CodeExplainSerializer(serializers.ModelSerializer):
class Meta:
model = CodeExplainer
fields = ("id", "_input", "_output")
extra_kwargs = {
"_output": {"read_only": True}
}
def create(self, validated_data):
code_explainer = CodeExplainer(**validated_data)
_output = send_code_to_api(validated_data["_input"])
code_explainer._output = _output
code_explainer.save()
return code_explainer
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ("id", "username", "email", "password")
extra_kwargs = {
"password": {"write_only": True}
}
def create(self, validated_data):
password = validated_data.pop("password")
user = User.objects.create(**validated_data)
user.set_password(password)
user.save()
Token.objects.create(user=user)
return user
class TokenSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField(style={"input_type": "password"}, trim_whitespace=False)
def validate(self, attrs):
username = attrs.get("username")
password = attrs.get("password")
user = authenticate(request=self.context.get("request"), username=username, password=password)
if not user:
msg = "Credentials are not provided correctly..."
raise serializers.ValidationError(msg, code="authentication")
attrs["user"] = user
return attrs