Django第三方功能的使用

Django第三方功能的使用

  • Django REST framework
    • 前言
    • 1、Django--Restframework--coreapi版文档
    • BUG:AssertionError: `coreapi` must be installed for schema support.
    • How to run Django with Uvicorn webserver?
    • 2、序列化类 Serializer的使用
    • 模型序列化类 ModelSerializer的使用
    • 序列化的嵌套使用
  • 验证码的生成和使用
  • 站内搜索引擎
    • 步骤(注意:有特殊要求)
    • Celery异步任务和定时任务
      • 异步任务
      • 定时任务

Django REST framework

前言

django-rest-framework官网

PYPI: djangorestframework
Django REST framework API 指南
参考博客

1、Django–Restframework–coreapi版文档

安装包
pip3 install djangorestframework
pip3 install markdown       # Markdown support for the browsable API.
pip3 install django-filter
pip3 install Pygments
pip3 install coreapi
pip3 install PyYAML项目url下设置文档路由
from rest_framework.documentation import include_docs_urls
urlpatterns = [path('admin/', admin.site.urls),path('docs/', include_docs_urls(title='My API Title')),
]项目settings
REST_FRAMEWORK = {# Use Django's standard `django.contrib.auth` permissions,# or allow read-only access for unauthenticated users.# 'DEFAULT_PERMISSION_CLASSES': [#     'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'  # 适用于添加身份验证和权限以后。# ]'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema' # (推荐) 因为新版的restframework需要指定默认schema# 或者 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}

BUG:AssertionError: coreapi must be installed for schema support.

解决办法:主要问题是urllib3的版本,降低版本

pip install urllib3==1.26.15

How to run Django with Uvicorn webserver?

问题:使用Uvicorn 运行的时候显示静态文件丢失
在这里插入图片描述

解决办法:

 settings.py 
STATIC_ROOT = os.path.join(BASE_DIR, 'static', )项目 urls.py
from django.conf.urls.static import static
from django.conf import settingsurlpatterns = [.
.....] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Then run below command but static directory must existpython manage.py collectstatic --noinput   # 收集静态文件
--noinput 参数的作用是执行收集静态文件的命令时不会询问任何输入,一般用于自动化脚本或者不需要交互式输入的场景
启动uvicorn
uvicorn your_project.asgi:application --reload --host 0.0.0.0 --port 8000

2、序列化类 Serializer的使用

serializers.py
import asynciofrom django.contrib.auth.models import Group, User
from rest_framework import serializersclass UserSerializer(serializers.HyperlinkedModelSerializer):class Meta:model = Userfields = ['url', 'username', 'email', 'groups']class GroupSerializer(serializers.HyperlinkedModelSerializer):class Meta:model = Groupfields = ['url', 'name']from .models import PersonInfo, VocationnameList = PersonInfo.objects.values('name').all()
NAME_CHOICES = [item['name'] for item in nameList]class MySerializer(serializers.Serializer):id = serializers.IntegerField(read_only=True)job = serializers.CharField(max_length=20)title = serializers.CharField(max_length=20)payment = serializers.IntegerField()name = serializers.PrimaryKeyRelatedField(queryset=NAME_CHOICES)  # models的外键字段def create(self, validated_data):return Vocation.objects.create(**validated_data)def update(self, instance, validated_data):return instance.update(**validated_data)
views.py
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsetsfrom .serializers import GroupSerializer, UserSerializerclass UserViewSet(viewsets.ModelViewSet):"""API endpoint that allows users to be viewed or edited."""queryset = User.objects.all().order_by('-date_joined')serializer_class = UserSerializer# permission_classes = [permissions.IsAuthenticated]class GroupViewSet(viewsets.ModelViewSet):"""API endpoint that allows groups to be viewed or edited."""queryset = Group.objects.all().order_by('name')serializer_class = GroupSerializer# permission_classes = [permissions.IsAuthenticated]from channels.db import database_sync_to_async
from .models import PersonInfo, Vocation
from .serializers import MySerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.decorators import api_view@api_view(['GET', 'POST'])
def vocationDef(request):if request.method == 'GET':q = Vocation.objects.all()pg = PageNumberPagination()p = pg.paginate_queryset(queryset=q, request=request)serializer = MySerializer(instance=p, many=True)return Response(serializer.data)elif request.method == 'POST':data = request.dataid = data['name']data['name'] = PersonInfo.objects.filter(id=id).first()instance = Vocation.objects.filter(id=data.get('id', 0))if instance:MySerializer().update(instance, data)else:MySerializer().create(data)return Response('Done', status=status.HTTP_201_CREATED)class VocationClass(APIView):def get(self, request):q = Vocation.objects.all()pg = PageNumberPagination()p = pg.paginate_queryset(queryset=q, request=request, view=self)serializer = MySerializer(instance=p, many=True)return Response(serializer.data)def post(self, request):data = request.dataid = data['name']data['name'] = PersonInfo.objects.filter(id=id).first()instance = Vocation.objects.filter(id=data.get('id', 0))if instance:MySerializer().update(instance, data)else:MySerializer().create(data)return Response('Done', status=status.HTTP_201_CREATED)

模型序列化类 ModelSerializer的使用

serializers.py
from rest_framework import serializers
class VocationSerializer(serializers.ModelSerializer):class Meta:model = Vocationfields = ('id', 'job', 'title', 'payment', 'name')
views.py
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsetsfrom .serializers import GroupSerializer, UserSerializerclass UserViewSet(viewsets.ModelViewSet):"""API endpoint that allows users to be viewed or edited."""queryset = User.objects.all().order_by('-date_joined')serializer_class = UserSerializer# permission_classes = [permissions.IsAuthenticated]class GroupViewSet(viewsets.ModelViewSet):"""API endpoint that allows groups to be viewed or edited."""queryset = Group.objects.all().order_by('name')serializer_class = GroupSerializer# permission_classes = [permissions.IsAuthenticated]from channels.db import database_sync_to_async
from .models import PersonInfo, Vocation
from .serializers import MySerializer, VocationSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.decorators import api_view@api_view(['GET', 'POST'])
def vocationDef(request):if request.method == 'GET':q = Vocation.objects.all()pg = PageNumberPagination()p = pg.paginate_queryset(queryset=q, request=request)serializer = VocationSerializer(instance=p, many=True)return Response(serializer.data)elif request.method == 'POST':id = request.data.get('id', 0)operation = Vocation.objects.filter(id=id).first()serializer = VocationSerializer(data=request.data)if serializer.is_valid():if operation:data = request.dataid = data['name']data['name'] = PersonInfo.objects.filter(id=id).first()serializer.update(operation, data)else:serializer.save()return Response(serializer.data)return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)class VocationClass(APIView):def get(self, request):q = Vocation.objects.all()pg = PageNumberPagination()p = pg.paginate_queryset(queryset=q, request=request, view=self)serializer = VocationSerializer(instance=p, many=True)return Response(serializer.data)def post(self, request):id = request.data.get('id', 0)operation = Vocation.objects.filter(id=id).first()serializer = VocationSerializer(data=request.data)if serializer.is_valid():if operation:data = request.dataid = data['name']data['name'] = PersonInfo.objects.filter(id=id).first()serializer.update(operation, data)else:serializer.save()return Response(serializer.data)return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)

序列化的嵌套使用

模型之间存在数据关系才能进行数据嵌套

class PersonInfoSerializer(serializers.ModelSerializer):class Meta:model = PersonInfofields = '__all__'class VocationSerializer(serializers.ModelSerializer):name = PersonInfoSerializer()class Meta:model = Vocationfields = ('id', 'job', 'title', 'payment', 'name')def create(self, validated_data):print('vad', validated_data)name = validated_data.get('name', '')id = name.get('id', 0)p = PersonInfo.objects.filter(id=id).first()if not p:p = PersonInfo.objects.create(**name)data = validated_datadata['name'] = pv = Vocation.objects.create(**data)return vdef update(self, instance, validated_data):print('vad', validated_data)name = validated_data.get('name', '')id = name.get('id', 0)p = PersonInfo.objects.filter(id=id).first()if p:PersonInfo.objects.filter(id=id).update(**name)data = validated_datadata['name'] = pid = validated_data.get('id', '')v = Vocation.objects.filter(id=id).update(**data)return v
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsetsfrom .serializers import GroupSerializer, UserSerializerclass UserViewSet(viewsets.ModelViewSet):"""API endpoint that allows users to be viewed or edited."""queryset = User.objects.all().order_by('-date_joined')serializer_class = UserSerializer# permission_classes = [permissions.IsAuthenticated]class GroupViewSet(viewsets.ModelViewSet):"""API endpoint that allows groups to be viewed or edited."""queryset = Group.objects.all().order_by('name')serializer_class = GroupSerializer# permission_classes = [permissions.IsAuthenticated]from channels.db import database_sync_to_async
from .models import PersonInfo, Vocation
from .serializers import MySerializer, VocationSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.decorators import api_view@api_view(['GET', 'POST'])
def vocationDef(request):if request.method == 'GET':q = Vocation.objects.all()pg = PageNumberPagination()p = pg.paginate_queryset(queryset=q, request=request)serializer = VocationSerializer(instance=p, many=True)return Response(serializer.data)elif request.method == 'POST':id = request.data.get('id', 0)operation = Vocation.objects.filter(id=id).first()serializer = VocationSerializer(data=request.data)if serializer.is_valid():if operation:serializer.update(operation, request.data)else:serializer.save()return Response(serializer.data)return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)class VocationClass(APIView):def get(self, request):q = Vocation.objects.all()pg = PageNumberPagination()p = pg.paginate_queryset(queryset=q, request=request, view=self)serializer = VocationSerializer(instance=p, many=True)return Response(serializer.data)def post(self, request):id = request.data.get('id', 0)operation = Vocation.objects.filter(id=id).first()serializer = VocationSerializer(data=request.data)if serializer.is_valid():if operation:serializer.update(operation, request.data)else:serializer.save()return Response(serializer.data)return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)

验证码的生成和使用

PYPI:django-simple-captcha

pip3 install django-simple-captcha==0.5.20
settings.py
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework',# 添加验证码功能'captcha',
]# Django Simple Captcha的基本配置
# 设置验证码的显示顺序
# 一个验证码识别包含文本输入框、隐藏域和验证码图片
# CAPTCHA_OUTPUT_FORMAT是设置三者的显示顺序
CAPTCHA_OUTPUT_FORMAT = '%(text_field)s %(hidden_field)s %(image)s'
# 设置图片噪点
CAPTCHA_NOISE_FUNCTIONS = ( # 设置样式'captcha.helpers.noise_null',# 设置干扰线'captcha.helpers.noise_arcs',# 设置干扰点'captcha.helpers.noise_dots',)
# 图片大小
CAPTCHA_IMAGE_SIZE = (100, 25)
# 设置图片背景颜色
CAPTCHA_BACKGROUND_COLOR = '#ffffff'
# 图片中的文字为随机英文字母
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
# 图片中的文字为英文单词
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.word_challenge'
# 图片中的文字为数字表达式
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
# 设置字符个数
CAPTCHA_LENGTH = 4
# 设置超时(minutes)
CAPTCHA_TIMEOUT = 1
生成数据表
python manage.py migrate
forms.py
from django import forms
from captcha.fields import CaptchaFieldclass CaptchaTestForm(forms.Form):username = forms.CharField(label='用户名')password = forms.CharField(label='密码', widget=forms.PasswordInput)captcha = CaptchaField()
项目urls
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from rest_framework.documentation import include_docs_urlsurlpatterns = [path('admin/', admin.site.urls),path('docs/', include_docs_urls(title='My API Title')),path('api-auth/', include('rest_framework.urls')),path('api/', include('apiwx.urls')),path('captcha/', include('captcha.urls')),   # 添加验证码路由
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
应用urls
from django.urls import include, path
from rest_framework import routersfrom . import viewsrouter = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [path('', include(router.urls)),path('func/', views.vocationDef),path('class/', views.VocationClass.as_view()),path('login/', views.loginView, name='login'),path('ajax_val/', views.ajax_val, name='ajax_val'),
]
views.pyfrom django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import login, authenticate
from .forms import CaptchaTestForm
# 用户登录
def loginView(request):if request.method == 'POST':form = CaptchaTestForm(request.POST)# 验证表单数据if form.is_valid():u = form.cleaned_data['username']p = form.cleaned_data['password']if User.objects.filter(username=u):user = authenticate(username=u, password=p)if user:if user.is_active:login(request, user)tips = '登录成功'else:tips = '账号密码错误,请重新输入'else:tips = '用户不存在,请注册'else:form = CaptchaTestForm()return render(request, 'user.html', locals())# ajax接口,实现动态验证验证码
from django.http import JsonResponse
from captcha.models import CaptchaStore
def ajax_val(request):if request.is_ajax():# 用户输入的验证码结果r = request.GET['response']# 隐藏域的value值h = request.GET['hashkey']cs = CaptchaStore.objects.filter(response=r, hashkey=h)# 若存在cs,则验证成功,否则验证失败if cs:json_data = {'status':1}else:json_data = {'status':0}return JsonResponse(json_data)else:json_data = {'status':0}return JsonResponse(json_data)
html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Django</title><script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css"></head><body><div class="flex-center"><div class="container"><div class="flex-center"><div class="unit-1-2 unit-1-on-mobile"><h1>MyDjango Verification</h1>{% if tips %}<div>{{ tips }}</div>{% endif %}<form class="form" action="" method="post">{% csrf_token %}<div>用户名:{{ form.username }}</div><div>密 码:{{ form.password }}</div><div>验证码:{{ form.captcha }}</div><button type="submit" class="btn btn-primary btn-block">确定</button></form></div></div></div></div><script>$(function(){$('.captcha').click(function(){console.log('click');$.getJSON("/captcha/refresh/",function(result){$('.captcha').attr('src', result['image_url']);$('#id_captcha_0').val(result['key'])});});$('#id_captcha_1').blur(function(){json_data={'response':$('#id_captcha_1').val(),'hashkey':$('#id_captcha_0').val()}$.getJSON('/ajax_val', json_data, function(data){$('#captcha_status').remove()if(data['status']){$('#id_captcha_1').after('<span id="captcha_status">*验证码正确</span>')}else{$('#id_captcha_1').after('<span id="captcha_status">*验证码错误</span>')}});});})</script></body>
</html>

站内搜索引擎

django-haystack 是专门提供搜索功能的DJango第三方应用,支持solr,elasticserch,whoosh,xapian多种搜索引擎,配合中文自然语言处理库jieba分词,可以实现全文搜索系统

pip3 install django-haystack
pip3 install whoosh
pip3 install jieba

步骤(注意:有特殊要求)

  • 在项目应用中添加 search_indexes.py和whoosh_cn_backend.py
  • 在项目的根目录创建文件夹 static和templates,static存放CSS样式文件,templates存放search.html和搜索引擎文件product_text.txt(文件的命名方式有具体的要求,下面会说明)
  1. search_indexes.py : 定义模型的索引类,使模型的数据能被搜索引擎搜索
  2. whoosh_cn_backend.py:自定义搜索引擎文件,由于Whoosh不支持中文搜索,重新定义搜索引擎文件,将jieba分词器添加到搜索引擎中,使其具有中文搜索功能
  3. product_text.txt:搜索引擎的索引模板文件,模板文件命名以及路径有固定格式,如:templates/search/indexes/项目应用的名称/模型名称(小写)_text.txt
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework',# 添加验证码功能'captcha',# 配置haystack'haystack',
]# 配置haystack
HAYSTACK_CONNECTIONS = {'default': {# 设置搜索引擎,文件是apiwx(应用)的whoosh_cn_backend.py'ENGINE': 'apiwx.whoosh_cn_backend.WhooshEngine','PATH': str(BASE_DIR / 'whoosh_index'),'INCLUDE_SPELLING': True,},
}
# 设置每页显示的数据量
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 4
# 当数据库改变时,会自动更新索引,非常方便
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
whoosh_cn_backend.py
# encoding: utf-8
# 文件来自haystack包,路径为Python\Lib\site-packages\haystack\backends\whoosh_backend.py
# 导入from jieba.analyse import ChineseAnalyzer包,添加中文搜索功能
# 将schema_fields[field_class.index_fieldname] = TEXT....的内容修改为:schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(),field_boost=field_class.boost, sortable=True)from haystack.backends.whoosh_backend import *
from jieba.analyse import ChineseAnalyzerclass MyWhooshSearchBackend(WhooshSearchBackend):def build_schema(self, fields):schema_fields = {ID: WHOOSH_ID(stored=True, unique=True),DJANGO_CT: WHOOSH_ID(stored=True),DJANGO_ID: WHOOSH_ID(stored=True),}# Grab the number of keys that are hard-coded into Haystack.# We'll use this to (possibly) fail slightly more gracefully later.initial_key_count = len(schema_fields)content_field_name = ''for field_name, field_class in fields.items():if field_class.is_multivalued:if field_class.indexed is False:schema_fields[field_class.index_fieldname] = IDLIST(stored=True, field_boost=field_class.boost)else:schema_fields[field_class.index_fieldname] = KEYWORD(stored=True, commas=True, scorable=True, field_boost=field_class.boost)elif field_class.field_type in ['date', 'datetime']:schema_fields[field_class.index_fieldname] = DATETIME(stored=field_class.stored, sortable=True)elif field_class.field_type == 'integer':schema_fields[field_class.index_fieldname] = NUMERIC(stored=field_class.stored, numtype=int, field_boost=field_class.boost)elif field_class.field_type == 'float':schema_fields[field_class.index_fieldname] = NUMERIC(stored=field_class.stored, numtype=float, field_boost=field_class.boost)elif field_class.field_type == 'boolean':# Field boost isn't supported on BOOLEAN as of 1.8.2.schema_fields[field_class.index_fieldname] = BOOLEAN(stored=field_class.stored)elif field_class.field_type == 'ngram':schema_fields[field_class.index_fieldname] = NGRAM(minsize=3, maxsize=15, stored=field_class.stored, field_boost=field_class.boost)elif field_class.field_type == 'edge_ngram':schema_fields[field_class.index_fieldname] = NGRAMWORDS(minsize=2, maxsize=15, at='start', stored=field_class.stored, field_boost=field_class.boost)else:schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(),field_boost=field_class.boost, sortable=True)if field_class.document is True:content_field_name = field_class.index_fieldnameschema_fields[field_class.index_fieldname].spelling = True# Fail more gracefully than relying on the backend to die if no fields# are found.if len(schema_fields) <= initial_key_count:raise SearchBackendError("No fields were found in any search_indexes. Please correct this before attempting to search.")return (content_field_name, Schema(**schema_fields))# 重新定义搜索引擎
class WhooshEngine(BaseEngine):# 将搜索引擎指向自定义的MyWhooshSearchBackendbackend = MyWhooshSearchBackendquery = WhooshSearchQuery
models.py
class Product(models.Model):id = models.AutoField('序号', primary_key=True)name = models.CharField('名称', max_length=50)weight = models.CharField('重量', max_length=20)describe = models.CharField('描述', max_length=500)# 设置返回值def __str__(self):return self.name
search_indexes.py
from haystack import indexes
from .models import Product
# 类名必须为模型名+Index
# 比如模型Product,则索引类为ProductIndex
class ProductIndex(indexes.SearchIndex, indexes.Indexable):text = indexes.CharField(document=True, use_template=True)# 设置模型def get_model(self):return Product# 设置查询范围def index_queryset(self, using=None):return self.get_model().objects.all()
# 定义索引类的文件名必须是 search_indexes.py, 不得修改文件名
# 模型的索引类的类名格式必须为 “模型名+Index”, 每个模型对应一个索引类,如果模型为Product,则对应的索引类为ProductIndex
# 字段text 设置document=True,表示搜索引擎以此字段的内容作为索引
# use_template=True 表示使用索引模板文件,可以理解为在模板中设置模型的查询字段,如设置Product的name字段,就可以通过name字段检索Product数据
# 类函数get_model是将索引类和模型进行绑定,index_queryset用于设置索引的查询范围
templates/search/indexes/项目应用的名称/模型名称(小写)_text.txt
索引模板文件{{ object.name }}
{{ object.describe }}# 对模型的name和describe 字段建立索引,当搜索引擎进行搜索的时候,Django根搜索条件对这两个字段进行全文搜索匹配,然后将结果排序返回
python manage.py rebuild_index   创建索引文件

在这里插入图片描述

views.py
from django.core.paginator import *
from django.shortcuts import render
from django.conf import settings
from .models import *
from haystack.generic_views import SearchView
# 视图以通用视图实现
class MySearchView(SearchView):# 模版文件template_name = 'search.html'def get(self, request, *args, **kwargs):if not self.request.GET.get('q', ''):product = Product.objects.all().order_by('id')per = settings.HAYSTACK_SEARCH_RESULTS_PER_PAGEp = Paginator(product, per)try:num = int(self.request.GET.get('page', 1))page_obj = p.page(num)except PageNotAnInteger:# 如果参数page不是整型,则返回第1页数据page_obj = p.page(1)except EmptyPage:# 访问页数大于总页数,则返回最后1页的数据page_obj = p.page(p.num_pages)return render(request, self.template_name, locals())else:return super().get(*args, request, *args, **kwargs)

Celery异步任务和定时任务

pip3 install celery   安装Celery框架实现异步任务和定时任务的调度控制
pip3 install redis  实现python和redis数据库的连接
pip3 install django-celery-results  基于Celery封装的异步任务功能
pip3 install django-celery-beat 基于Celery封装的定时任务功能
pip3 install eventlet   python的协程并发库,这是celery实现异步并发运行的模式之一
settings 中配置异步功能
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',# 添加异步任务功能'django_celery_results',# 添加定时任务功能'django_celery_beat',
]# 设置存储Celery任务队列的Redis数据库
CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
# 设置存储Celery任务结果的数据库
CELERY_RESULT_BACKEND = 'django-db'# 设置定时任务相关配置
CELERY_ENABLE_UTC = False
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
modles.py 
from django.db import models# Create your models here.
class PersonInfo(models.Model):name = models.CharField(max_length=20)age = models.IntegerField()hireDate = models.DateField()def __str__(self):return self.name
数据迁移
python manage.py makemigrations
python manage.py migrate
项目下创建celery.py  (settings同目录)
创建celery框架的实例化对象
import os
from celery import Celery
# 获取settings的配置信息
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web2.settings")
# 定义celery对象,并将项目配置信息加载到对象中
# Celery的参数一般以项目名命名
app = Celery('web2')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()项目下的 __init__.py
将celery实例化对象和django 绑定
# django运行的时候自动加载celery实例化对象
from .celery import app as celery_app
__all__ = ['celery_app']

异步任务

应用下创建task.py
开发异步任务
from celery import shared_task
from .models import PersonInfo
import time# 带参数的异步任务
@shared_task
def updateDate(id, kwargs):try:PersonInfo.objects.filter(id=id).update(**kwargs)return "Done"except Exception as e:print('error', e)return 'Fail'
开发视图,并在urls中添加路由地址
views.py
from django.http import HttpResponse
from .task import updateDate
def tasksyn(request):id = request.GET.get('id', 1)kwarg = dict(name='mike', age=19, hireDate='2024-04-13')updateDate.delay(id, kwarg)return HttpResponse('hello celery')
先启动django
uvicorn web2(项目名).asgi:application --reload --host 0.0.0.0 --port 8000
再启动异步任务
celery -A projectName worker -l info -P eventlet

定时任务

from celery import shared_task
from .models import PersonInfo
import time# 带参数的异步任务
@shared_task
def updateDate(id, kwargs):try:PersonInfo.objects.filter(id=id).update(**kwargs)return "Done"except Exception as e:print('error', e)return 'Fail'# 定时任务
@shared_task
def timing():now = time.strftime("%H:%M:%S")with open('output.txt', 'a') as f:f.write('The time is ' + now)f.write('\n')

在这里插入图片描述
进入后台,设置定时任务,
Name:给定时任务取名,任意
Task(registered):task.py 开发的定时任务
Interval Schedule:设置时间间隔
PS:如果任务带参数,可在Add periodic task 中设置Arguments 或者 Keyword argument

先启动django
uvicorn web2(项目名).asgi:application --reload --host 0.0.0.0 --port 8000
再启动异步任务
celery -A projectName worker -l info -P eventlet
再启动定时任务
celery -A projectName beat -l info -S django

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/816261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 社区版 安装总结

很早就安装过MySQL&#xff0c;没有遇到过什么问题&#xff0c;直接next就行了&#xff0c;这次在新电脑上安装却遇到了一些问题&#xff0c;记录一下。 安装的是MySQL社区版&#xff0c;下载地址是www.mysql.com&#xff0c;进入后选择DOWNLOAD页面&#xff0c;选择MySQL Com…

SqlServer专题

目录 1&#xff0c;连接数据库 2&#xff0c;连接池 1.何为连接池&#xff1f; 2.连接池运行原理。 3.如何查看连接池&#xff1f; 4.连接池注意事项。 3&#xff0c;一般SQL语句。 4&#xff0c;控制语句 1.判断语句 2.循环语句 5&#xff0c;视图 1.使用…

<计算机网络自顶向下> P2P应用

纯P2P架构 没有或者极少一直运行的Server&#xff0c;Peer节点间歇上网&#xff0c;每次IP地址都可能变化任意端系统都可以直接通信利用peer的服务能力&#xff0c;可扩展性好例子&#xff1a;文件分发; 流媒体; VoIP类别:两个节点相互上载下载文件&#xff0c;互通有无&#…

C# Solidworks二次开发:相机访问相关API详解

大家好&#xff0c;今天要介绍的API为相机相关的API&#xff0c;这篇文章比较适合女孩子&#xff0c;学会了相机就会拍照了&#xff0c;哈哈。 下面是要介绍的API: &#xff08;1&#xff09;第一个为GetFocalDistance&#xff0c;这个API的含义为获取相机的焦距&#xff0c;…

ASP.NET基于BS的图书销售管理系统的设计与实现

随着Internet的兴起&#xff0c;网络已经成为现代人生活中的一部分&#xff0c;越来越多的人喜欢在网上交易。本系统就是一个基于B/S模式的网络化的图书销售管理系统,采用的是ASP.NET技术&#xff0c;实现了用户注册信息管理、用户信息管理、图书销售点管理、图书信息管理、客户…

特征工程(IV)--特征选择

特征工程 有这么一句话在业界广泛流传&#xff1a;数据和特征决定了机器学习的上限&#xff0c;而模型和算法只是逼近这个上限而已。由此可见&#xff0c;特征工程在机器学习中占有相当重要的地位。在实际应用当中&#xff0c;可以说特征工程是机器学习成功的关键。 特征工程是…

【C语言】简易版扫雷+进阶版扫雷

目录 前言 一、分模块化 二、准备雷盘 2.1 游戏菜单 2.2 创建雷盘思路 2.3 构建雷盘 2.4 雷盘展示 2.4.1 初始化雷盘 2.4.2 打印雷盘 三、排雷 3.1 布置雷 3.2 排查雷 四、进阶版扫雷 总结 前言 C语言实现扫雷小游戏&#xff0c;帮我们更进一步的掌握数组、模块化…

Windows Server 2016虚拟机安装教程

一、VMware Workstation虚拟机软件的下载 官网下载入口&#xff1a;​​​​​​Download VMware Workstation Pro - VMware Customer Connect​​​​​ 下载好之后自己看着提示安装软件就好. 二、镜像文件的下载 下载网站入口&#xff1a;MSDN, 我告诉你 - 做一个安静…

【Java EE】Spring核心思想(一)——IOC

文章目录 &#x1f38d;Spring 是什么&#xff1f;&#x1f384;什么是IoC呢&#xff1f;&#x1f338;传统程序开发&#x1f338;传统程序开发的缺陷&#x1f338;如何解决传统程序的缺陷&#xff1f;&#x1f338;控制反转式程序开发&#x1f338;对比总结 &#x1f332;理解…

汇编语言知识点整理(应付考试专用,想学习找其他的)

1 基础知识 1.1 信息在计算机内部的表示和存储 1.1.1 信息存储的基本概念 信息在计算机内部是以二进制数据的形式在存储器中存取的。介绍两个基本概念&#xff1a; 位&#xff08;Bit&#xff09; 计算机中最小的数据单位&#xff0c;一位有0、1两状态。Bit是计算机中最小…

MySQL优化表,表的碎片整理和空间回收,清理空间

1.sql -- 查看表占用空间大小。简单查询可以用show table status like blog_visit; select data_length, index_length, data_free, o.* from information_schema.tables o where table_schema in (lishuoboy-navigation) and table_nameblog_visit order by data_length des…

计算机服务器中了rmallox勒索病毒怎么办,rmallox勒索病毒解密流程步骤

在企业的生产运营过程中网络发挥着巨大作用&#xff0c;利用网络可以拓宽市场&#xff0c;提高办公效率&#xff0c;网络为企业的生产运营提供了极大便利&#xff0c;但也为企业的数据安全带来隐患。近日&#xff0c;云天数据恢复中心接到多家企业的求助&#xff0c;企业的计算…

使用 Verdaccio 私有化 npm 源指南

使用 Verdaccio 私有化 npm 源指南 使用 Verdaccio 私有化 npm 源指南 介绍什么是 Verdaccio为什么选择 Verdaccio部署 Verdaccio Nodejs 部署 全局局部 Docker 部署云服务商一键部署 注册用户发布私有 npm 包管理 npm 包项目使用私有源 全量切换部分切换 结尾源代码链接 介…

网络篇10 | 网络层 IP

网络篇10 | 网络层 IP 01 简介02 名称解释03 IP报文格式(IPv4)1&#xff09;4位版本协议(version)2&#xff09;4位首部长度(header length)3&#xff09;8位服务类型(Type Of Service, TOS)4&#xff09;16位总长度5&#xff09;16位(分片)标识6&#xff09;3位(分片)标志7&am…

Spring Cloud 集成 RabbitMQ

目录 前言步骤引入相关maven依赖添加相关配置 使用方法配置消息序列化创建第一个消息队列和交换机使用方法 总结 前言 在当今的微服务架构盛行的时代&#xff0c;消息队列作为一种重要的通信机制&#xff0c;在分布式系统中扮演着不可或缺的角色。RabbitMQ&#xff0c;作为一款…

ASP.NET公交车管理系统的实现与设计

摘 要 随着经济的日益增长&#xff0c;信息化时代已经到来&#xff0c;生活中各种信息趋向数字化、清晰化。公交车作为现代城市生活中一种重要的交通工具&#xff0c;其数量增多&#xff0c;车型也不再单一&#xff0c;雇用的司机增多&#xff0c;这样使得公交车公司的车辆信…

XTTS数据迁移方案

前置条件检查 XTTS使用限制较多&#xff0c;V3版本按照本节逐项检查 目标库操作系统不能是windows 源库&#xff1a;redhut 7.9 目标库&#xff1a;redhut 7.9 检查数据库时区&#xff08;两边都需要&#xff09; SQL> select dbtimezone from dual; 检查结果两边都一致…

机器学习和深度学习--李宏毅 (笔记与个人理解)Day 16

Day 16 deep Learning – 鱼与熊掌兼得 最近在减重&#xff0c; 昨天跑了个一公里&#xff0c;然后今天上午又打了个篮球&#xff0c;真是老胳膊老腿了&#xff0c;运动完给我困得不行 Review 见前面的笔记 这里说dl 会提供一个足够大的模型&#xff0c; 来使得Dall loss 足够小…

Unity类银河恶魔城学习记录12-14 p136 Merge Skill Tree with Sword skill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili CharacterStats.cs using System.Collections; using System.Collections.…

【氮化镓】GaN HEMTs结温和热阻测试方法

文章《Temperature rise detection in GaN high-electron-mobility transistors via gate-drain Schottky junction forward-conduction voltages》&#xff0c;由Xiujuan Huang, Chunsheng Guo, Qian Wen, Shiwei Feng, 和 Yamin Zhang撰写&#xff0c;发表在《Microelectroni…