后端代码:# gouw/routing.py
from django.urls import path
from .consumers import OrderConsumer
websocket_urlpatterns = [
path('ws/orders/', OrderConsumer.as_asgi()), # 定义 WebSocket 路由
] # gouw/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class OrderConsumer(AsyncWebsocketConsumer):
async def connect(self):
# 接受 WebSocket 连接
await self.accept()
async def disconnect(self, close_code):
# 处理连接断开
pass
async def receive(self, text_data):
# 接收消息
text_data_json = json.loads(text_data)
message = text_data_json['message']
# 发送消息回客户端
await self.send(text_data=json.dumps({
'message': message
})) # DjangoProject1/routing.py
from django.urls import re_path
from channels.routing import ProtocolTypeRouter, URLRouter
from gouw.consumers import OrderConsumer # 替换为你的实际消费者
websocket_urlpatterns = [
re_path(r'ws/some-path/', OrderConsumer.as_asgi()),
]
application = ProtocolTypeRouter({
"websocket": URLRouter(websocket_urlpatterns),
})
"""
ASGI config for DjangoProject1 project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""
# import os
#
# from django.core.asgi import get_asgi_application
#
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoProject1.settings')
#
# application = get_asgi_application()
# DjangoProject1/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from .routing import websocket_urlpatterns # 添加这行
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoProject1.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": URLRouter(websocket_urlpatterns), # 使用导入的路由
}) """
Django settings for DjangoProject1 project.
Generated by 'django-admin startproject' using Django 5.1.6.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""
import os
from datetime import timedelta
from pathlib import Path
# import AES
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-7f5y$m$)-y81w5h0q*o12ohp$douez_97h-x_!daldl@9%7kvr'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
# 通用
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework_simplejwt', # 新增
# 功能
'rest_framework',
'corsheaders',
'django_filters',
'rest_framework.authtoken',
'channels'
# app
'swiper',
'search', # 正确的应用名称
'merchant', # 正确的应用名称
'shop',
"product",
"gouw",
"xiad",
"zhif",
"dd",
'wod_denglu',
"dingd",
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'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',
]
ASGI_APPLICATION = "DjangoProject1.asgi.application"
TIME_ZONE = 'Asia/Shanghai' # 确保时区正确
USE_TZ = True
CORS_ALLOW_ALL_ORIGINS = True
ROOT_URLCONF = 'DjangoProject1.urls'
# TEMPLATES = [
# { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
# 'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [BASE_DIR / 'templates']
# ,
# 'APP_DIRS': True,
# 'OPTIONS': {
# 'context_processors': [
# 'django.template.context_processors.debug',
# 'django.template.context_processors.request',
# 'django.contrib.auth.context_processors.auth',
# 'django.contrib.messages.context_processors.messages',
# ],
# },
# },
# ]
CORS_ALLOWED_ORIGINS = [
'http://127.0.0.1:8000', # 替换为实际的前端地址
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'DjangoProject1.wsgi.application'
CORS_ORIGIN_ALLOW_ALL = True
# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':"db_44",
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
'charset': 'utf8mb4',
}
}
# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
CORS_ALLOW_CREDENTIALS = True
# DRF配置
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'ORDERING_PARAM': 'ordering',
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
],
# "DEFAULT_AUTHENTICATION_CLASSES": (
# 'rest_framework.permissions.IsAuthenticated',
# ),
# "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
#
# 'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.TokenAuthentication',
# ],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
# 'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
# 'rest_framework_simplejwt.authentication.JWTAuthentication', # 替换原来的 JWT 认证
# #Token认证
# 'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
),
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
}
AUTH_USER_MODEL = 'wod_denglu.User'
# AUTH_USER_MODEL = None # 替换为实际应用名
# 配置文件上传路径
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
# 在settings.py 中启用调试模式
DEBUG = True
# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# #
# LOGGING = {
# 'version': 1,
# 'disable_existing_loggers': False,
# 'handlers': {
# 'console': {
# 'level': 'DEBUG',
# 'class': 'logging.StreamHandler',
# },
# },
# 'loggers': {
# 'django': {
# 'handlers': ['console'],
# 'level': 'DEBUG',
# },
# },
# }
# 允许所有域名(开发环境临时方案)
CORS_ORIGIN_ALLOW_ALL = True
# 配置允许的请求头
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
# 配置允许的HTTP方法
CORS_ALLOW_METHODS = [
'GET',
'POST',
'PUT',
'DELETE',
'OPTIONS'
]
#
# # 增强型JWT配置
# JWT_SETTINGS = {
# 'SECRET_KEY': os.getenv('JWT_SECRET'), # 32位随机字符串
# 'ALGORITHM': 'HS256',
# 'ACCESS_TOKEN_LIFETIME': timedelta(hours=2),
# 'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
# 'AUTH_HEADER_PREFIX': 'Bearer'
# }
# # 微信配置
# WECHAT = {
# 'APP_ID': os.environ.get('WECHAT_APP_ID'),
# 'APP_SECRET': os.environ.get('WECHAT_APP_SECRET'),
# 'LOGIN_URL': 'https://api.weixin.qq.com/sns/jscode2session'
# }
#
# # AES加密配置(用于手机号解密)
# AES_SETTINGS = {
# 'MODE': AES.MODE_CBC,
# 'BLOCK_SIZE': 32,
# 'PADDING': '\0'
# }
# 微信配置
WX_APPID= 'wx5bb48b2fd7ec3e54'
WX_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200'
WX_MCHID = '1230004567' # 新增
WX_API_KEY = 'aBcDeFgHiJkLmNoPqRsTuVwXyZ' # 新增
WX_NOTIFY_URL = 'http:/http://127.0.0.1:8000/api/zhif/wx-notify/'
WECHAT_APPID = 'wx5bb48b2fd7ec3e54'
WECHAT_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200'
WECHAT_APP_ID = 'wx5bb48b2fd7ec3e54'
WECHAT_APP_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200'
WECHAT_MINI_PROGRAM = {
'APPID': 'wx5bb48b2fd7ec3e54',
'SECRET': '6ba10b53c9bdf24aaa0f026f147e0200'
}
WECHAT_TOKEN = "90_RzkT6EObTjmOA4E0O2ouANm7iYvTauxbwnTFkcTEu-3ggitiQnpzpvHE6-JUfbGThiqvmOdHBF4TEE3rf9GE_1MvDoBzhPEIj24OWmT0ulQkJ4iq95JweKmIBa8OQZfAGASUD"
# 默认头像配置
DEFAULT_AVATAR_URL = 'https://tse2-mm.cn.bing.net/th/id/OIP-C.1eW3_u1T8He1QmfKH_ctngAAAA?rs=1&pid=ImgDetMain'
# JWT配置
JWT_EXPIRATION_DAYS = 7
SIMPLE_JWT = {
# 'AUTH_TOKEN_CLASSES': ('shop.auth.ShopJWTAuthentication',),
# # 'TOKEN_USER_CLASS': 'shop.models.Shop',
# 'USER_ID_FIELD': 'id',
# 'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'shop.auth.allow_all_users', # 新增规则
# 添加商家用户类型支持
'TOKEN_USER_CLASSES': (
'wod_denglu.models.User',
'shop.models.Shop'
),
# 'AUTH_TOKEN_CLASSES': ('shop.auth.ShopJWTAuthentication',),
# 'USER_ID_FIELD': 'uuid', # 使用唯一标识字段
'TOKEN_USER_CLASS': 'wod_denglu.models.User', # 主用户类
'TOKEN_OBTAIN_SERIALIZER': 'wod_denglu.serializers.CustomTokenObtainPairSerializer',
# 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'ACCESS_TOKEN_LIFETIME': timedelta(days=7), # 按需配置有效期
'REFRESH_TOKEN_LIFETIME': timedelta(days=30),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
# 调试专用配置
'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','shop.auth.ShopJWTAuthentication'),
'TOKEN_TYPE_CLAIM': 'token_type',
# 开启详细错误
'SHOW_AUTHENTICATION_ERRORS': True,
'SIGNING_KEY': '6ba10b53c9bdf24aaa0f026f147e0200', # 替换为强密钥
}
# 安全配置
SECRET_KEY = '6ba10b53c9bdf24aaa0f026f147e0200'
# AUTHENTICATION_BACKENDS = [
# 'django.contrib.auth.backends.ModelBackend',
# 'shop.backends.ShopBackend', # 如果你使用自定义后端
# ]
# # 指定自定义用户模型
# AUTH_USER_MODEL = 'shop.Shop' # 根据应用名调整
# 配置认证后端
AUTHENTICATION_BACKENDS = [
'shop.backends.ShopAuthBackend', # 商家认证
'wod_denglu.backends.CustomerAuthBackend', # 消费者认证
'django.contrib.auth.backends.ModelBackend',
]
# JWT配置
# SIMPLE_JWT = {
# 'USER_ID_FIELD': 'id',
# 'USER_ID_CLAIM': 'user_id',
# 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
# }
#
# # 认证后端配置
# AUTHENTICATION_BACKENDS = [
# 'django.contrib.auth.backends.ModelBackend',
# 'shop.backends.ShopBackend',
# ]
#
# # 用户模型配置
# AUTH_USER_MODEL = 'shop.Shop'
#
# # JWT配置
# SIMPLE_JWT = {
# 'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
# 'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
# 'ROTATE_REFRESH_TOKENS': False,
# 'BLACKLIST_AFTER_ROTATION': True,
# 'ALGORITHM': 'HS256',
# 'SIGNING_KEY': SECRET_KEY,
# 'VERIFYING_KEY': None,
# 'AUTH_HEADER_TYPES': ('Bearer',),
# 'USER_ID_FIELD': 'id',
# 'USER_ID_CLAIM': 'user_id',
# 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
# }
DATA_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10MB
FILE_UPLOAD_MAX_MEMORY_SIZE = 2 * 1024 * 1024 # 2MB
FILE_UPLOAD_PERMISSIONS = 0o644
# LOGGING = {
# 'version': 1,
# 'disable_existing_loggers': False,
# 'handlers': {
# 'file': {
# 'level': 'DEBUG',
# 'class': 'logging.FileHandler',
# 'filename': 'debug.log',
# },
# 'console': {
# 'level': 'DEBUG',
# 'class': 'logging.StreamHandler',
# },
# },
# 'loggers': {
# 'django': {
# 'handlers': ['file', 'console'],
# 'level': 'DEBUG',
# 'propagate': True,
# },
# },
# } 后端报错:C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Scripts\python.exe D:\ajango后端项目\DjangoProject1\manage.py runserver 8000
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:\Users\马加帅\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1073, in _bootstrap_inner
self.run()
File "C:\Users\马加帅\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\core\management\commands\runserver.py", line 126, in inner_run
autoreload.raise_last_exception()
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\utils\autoreload.py", line 87, in raise_last_exception
raise _exception[1]
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\core\management\__init__.py", line 394, in execute
autoreload.check_errors(django.setup)()
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\apps\registry.py", line 91, in populate
app_config = AppConfig.create(entry)
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\马加帅\PycharmProjects\PythonProject2\.venv\Lib\site-packages\django\apps\config.py", line 193, in create
import_module(entry)
File "C:\Users\马加帅\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'channelsswiper'