本文为 React 项目(在线计算器)的下篇内容,主要为后端部分的开发,上篇可见:React 小项目-在线计算器(上)。
我们先在项目根目录下打开终端,创建一个 Python 虚拟环境:
python -m venv venv
启动虚拟环境:
.\venv\Scripts\Activate.ps1
安装环境:
pip install django
npm i jquery
查看 Django 版本:
django-admin --version
创建 Django 项目:
django-admin startproject calculator_django
同步数据库的修改:
python manage.py migrate
启动 Django 项目:
python manage.py runserver localhost:8000
创建管理员用户(假设用户名和密码都为 admin
):
python manage.py createsuperuser
创建新的 App:
python manage.py startapp app
将 app
目录中的 views.py
和 models.py
删除,创建 views
、models
、urls
文件夹,并在这三个目录下创建好 __init__.py
文件。
更新一下总 URL 文件(calculator_django/calculator_django/urls.py
):
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('app.urls.index')),
path('admin/', admin.site.urls),
]
接着进行一些项目的全局设置,首先设置一下项目的时区,打开 calculator_django/calculator_django/settings.py
(之后的操作均在该文件中),修改 TIME_ZONE
:
TIME_ZONE = 'Asia/Shanghai'
为防止出现跨域问题,我们可以添加以下一行代码:
SECURE_CROSS_ORIGIN_OPENER_POLICY = 'None'
然后将自己创建的 App 加载进来,找到 INSTALLED_APPS
,将 app/apps.py
添加进来:
INSTALLED_APPS = [
'app.apps.AppConfig', # 添加此行
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
找到 STATIC_URL = 'static/'
,在其附近添加几行:
import os # 在文件首部导入包
STATIC_ROOT = os.path.join(BASE_DIR, 'static') # 表示要将静态文件放到static目录下
STATIC_URL = 'static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = 'media/'
我们在 app
目录中创建 static
文件夹,之后即可通过链接 http://localhost:8000/static/xxx
访问 static
目录中的静态文件。
我们在 calculator_django/app/views
目录下创建 login.py
:
from django.contrib.auth import authenticate, login
from django.http import JsonResponse
def mylogin(request):
data = request.GET
username = data.get('username')
password = data.get('password')
user = authenticate(username=username, password=password)
if not user:
return JsonResponse({
'result': 'Username or password wrong!',
})
login(request, user)
return JsonResponse({
'result': 'success',
})
然后创建 logout.py
:
from django.contrib.auth import logout
from django.http import JsonResponse
def mylogout(request):
user = request.user
if not user.is_authenticated:
return JsonResponse({
'result': 'success',
})
logout(request)
return JsonResponse({
'result': 'success',
})
然后创建 register.py
:
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.http import JsonResponse
def register(request):
data = request.GET
username = data.get('username', '').strip() # 如果没有的话返回空,且过滤掉空格
password = data.get('password', '').strip()
confirm_password = data.get('confirm_password', '').strip()
if not username or not password: # 用户名或密码为空
return JsonResponse({
'result': 'Username or password can\'t be empty!',
})
elif password != confirm_password: # 两次密码不一致
return JsonResponse({
'result': 'Password inconsistency!'
})
elif User.objects.filter(username=username).exists(): # 用户名已存在
return JsonResponse({
'result': 'Username has existed!'
})
user = User(username=username)
user.set_password(password)
user.save()
login(request, user)
return JsonResponse({
'result': 'success',
})
现在在 calculator_django/app/urls
目录中编写路由 index.py
:
from django.urls import path
from app.views.login import mylogin
from app.views.logout import mylogout
from app.views.register import register
urlpatterns = [
path('login/', mylogin, name='login'),
path('logout/', mylogout, name='logout'),
path('register/', register, name='register'),
]
现在我们实现登录界面(login.jsx
文件):
import React, {
Component } from 'react';
import Card from './card';
import $ from 'jquery';
class Login extends Component {
state = {
username: '',
password: '',
error_message: '', // 错误信息提示
};
handleLogin = (e) => {
e.preventDefault(); // 阻止默认的提交行为,之后用ajax提交
this.setState({
error_message: