环境及项目配置
1.django-admin startproject acapp
启动项目
2./acapp/settings.py
ALLOWED_HOSTS
中加入服务器IP, python3 manage.py runserver 0.0.0.0:8000
跑通
3.python3 manage.py startapp game
创建game app
4.登录django管理员界面
python3 manage.py migrate
同步一下数据库的修改
python3 manage.py createsuperuser
创建管理员账号
IP地址:8000/admin # 进到管理员登录界面,输入一下刚才创建的账号即可进到管理员界面
5./acapp/settings.py
中还有几个修改的地方
INSTALLED_APPS
添加game.apps.GameConfig
- 修改时区
TIME_ZONE = 'Asia/Shanghai'
- 静态文件根目录
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
- 静态文件根目录
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'
6./game/
下创建文件夹models
、views
、urls
、templates
、static
,前三个创建__init__.py
7.static
下创建文件夹image
、css
、js
8.每个文件夹下创建menu
、playground
、settings
分别管理
表单配置
添加表单
acapp/game/models是用于储存信息的,所以我们可以在这里面储存用户信息。
定义一个数据表,首先进入acapp/game/models/创建一个player文件夹并进入,再创建py文件__init__.py和player.py。
player.py示例
# 用 Django 自带的基类扩充
from django.db import models # 从django的数据库中引入models
from django.contrib.auth.models import User # 从django中引入这个基本的User类
class Player(models.Model): # 要从models.Model这个类来继承
user = models.OneToOneField(User, on_delete = models.CASCADE) # Player从User扩充,这里是定义一个扩充关系,代表Player都有唯一对应的User,User就是代表User数据表,on_delete代表删除User的时候,把他对应的Player也删掉
photo = models.URLField(max_length = 256, blank = True) # 代表头像的URL,max_length是链接最大长度,blank是是否可空
def __str__(self):
return str(self.user)
在acapp/game/admin.py
中添加
admin.py示例
from django.contrib import admin
from game.models.player.player import Player # 引入自己定义的数据表
admin.site.register(Player) # 注册这个数据表
执行
python3 manage.py makemigrations
python3 manage.py migrate
配置django_redis
1. 安装django_redis
pip install django_redis
2. 配置settings.py
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
},
}
USER_AGENTS_CACHE = 'default'
3. 启动redis-server
sudo redis-server /etc/redis/redis.conf
配置 channels_redis
1. 安装channels_redis:
install channels_redis
2. 配置acapp/asgi.py
内容如下:
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from game.routing import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'acapp.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(URLRouter(websocket_urlpatterns))
})
3. 配置acapp/settings.py
在INSTALLED_APPS
中添加channels
,添加后如下所示:
INSTALLED_APPS = [
'channels',
'game.apps.GameConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
然后在文件末尾添加:
ASGI_APPLICATION = 'acapp.asgi.application'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
},
},
}
4. 配置game/routing.py
这一部分的作用相当于http
的urls
。
内容如下:
from django.urls import path
websocket_urlpatterns = [
]
5. 编写game/consumers
这一部分的作用相当于http
的views
。
参考示例:
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class MultiPlayer(AsyncWebsocketConsumer):
async def connect(self):
await self.accept()
print('accept')
self.room_name = "room"
await self.channel_layer.group_add(self.room_name, self.channel_name)
async def disconnect(self, close_code):
print('disconnect')
await self.channel_layer.group_discard(self.room_name, self.channel_name)
async def receive(self, text_data):
data = json.loads(text_data)
print(data)
6. 启动django_channels
在~/acapp目录下执行:
daphne -b 0.0.0.0 -p 5015 acapp.asgi:application
Rest Framework与JWT身份验证
安装
pip install djangorestframework
pip install pyjwt
pip install djangorestframework-simplejwt
然后在settings.py
的INSTALLED_APPS
中添加rest_framework
,rest_framework_simplejwt
,
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}