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.rhkb.cn/news/313308.html

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

相关文章

linux 安装openjdk-1.8

安装命令 yum install java-1.8.0-openjdk-1.8.0.262.b10-1.el7.x86_64查看安装路径 find / -name java 默认的安装路径 /usr/lib/jvm 查看到jre 以及java-1.8.0-openjdk-1.8.0.262.b10-1.el7.x86_64 配置环境变量 vim /etc/profile 添加的内容 export JAVA_HOME/usr/li…

【面试经典 150 | 二分查找】寻找两个正序数组的中位数

文章目录 写在前面Tag题目来源题目解读方法一&#xff1a;朴素方法二&#xff1a;二分查找【寻找第k小元素】 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附…

[大模型]Qwen-7B-hat Transformers 部署调用

Qwen-7B-hat Transformers 部署调用 环境准备 在autodl平台中租一个3090等24G显存的显卡机器&#xff0c;如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下…

华为机考入门python3--(15)牛客15-求int型正整数在内存中存储时1的个数

分类&#xff1a;二进制 知识点&#xff1a; int转二进制 binary bin(n)[2:] 题目来自【牛客】 def count_ones_in_binary(n): # 将输入的整数转换为二进制字符串 # bin(n)为0b11011binary bin(n)[2:]# 初始化计数器为0 count 0 # 遍历二进制字符串的每一位 fo…

LoRA模型是什么?

AI Agent能力评测工具AgentBench评测结果 LoRA模型是什么&#xff1f; LoRA模型&#xff08;Low-Rank Adaptation of Large Language Models&#xff09;是一种针对大型语言模型&#xff08;LLMs&#xff09;的微调技术&#xff0c;其目的是在保持模型原有性能的基础上&#x…

YOLTV8 — 大尺度图像目标检测框架(欢迎star)

YOLTV8 — 大尺度图像目标检测框架【ABCnutter/YOLTV8: &#x1f680;】 针对大尺度图像&#xff08;如遥感影像、大尺度工业检测图像等&#xff09;&#xff0c;由于设备的限制&#xff0c;无法利用图像直接进行模型训练。将图像裁剪至小尺度进行训练&#xff0c;再将训练结果…

未来课堂革命:OpenAI 发布 ChatGPT 使用指南,探索生成式 AI 如何重塑教育景观

随着新学期的来临&#xff0c;众多初登教师舞台的 00 后们&#xff0c;也完成了他们的第一个教师身份下的暑期生活。 对于开学的抵触情绪&#xff0c;不仅学生们普遍存在&#xff0c;许多 00 后的新晋教师们也同样感同身受。某种程度上&#xff0c;这些抗拒上班的年轻教师群体…

Springboot+Vue项目-基于Java+MySQL的高校心理教育辅导系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

【面试题】MySQL 事务的四大特性说一下?

事务是一个或多个 SQL 语句组成的一个执行单元&#xff0c;这些 SQL 语句要么全部执行成功&#xff0c;要么全部不执行&#xff0c;不会出现部分执行的情况。事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。 事务的主要作用是保证数…

金蝶云星空与金蝶云星空对接集成委外超耗查询连通生产订单变更(发顺丰)

金蝶云星空与金蝶云星空对接集成委外超耗查询连通生产订单变更(发顺丰) 对接系统金蝶云星空 金蝶K/3Cloud在总结百万家客户管理最佳实践的基础上&#xff0c;提供了标准的管理模式&#xff1b;通过标准的业务架构&#xff1a;多会计准则、多币别、多地点、多组织、多税制应用框…

FPGA - ZYNQ 基于EMIO的PS和PL交互

前言&#xff1a; Xilinx ZYNQ系列的芯片&#xff0c;GPIO分为 MIO 、EMIO、AXI_GPIO三种方式。 MIO &#xff1a;固定管脚&#xff0c;属于PS端&#xff0c;也就是ARM端。 EMIO &#xff1a;通过PL扩展&#xff0c;使用时需要分配PL(FPGA)管脚&#xff0c;消耗PL端资源。…

【GPT-4最新研究】GPT-4与科学探索:揭秘语言模型在科学领域的无限可能

各位朋友们&#xff0c;你们知道吗&#xff1f;自然语言处理领域最近取得了巨大的突破&#xff01;大型语言模型&#xff08;LLM&#xff09;的出现&#xff0c;简直就像打开了新世界的大门。它们不仅在语言理解、生成和翻译方面表现出色&#xff0c;还能涉足许多其他领域&…

二叉树的中序遍历 - LeetCode 热题 36

大家好&#xff01;我是曾续缘&#x1f603; 今天是《LeetCode 热题 100》系列 发车第 36 天 二叉树第 1 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输…

React-路由(一)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;React篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来React篇专栏内容:React-路由&#xff08;一&#xff09; 目录 1、介绍 2、路由的使用 2.1、相关组件 2.2、声…

白话微机:10.民风淳朴的MCS-51小镇(小镇方言:汇编)

1. 基本结构与周期 MCS-51系列单片机属于8位单片机用 8051单片机构成最小应用系统时&#xff0c;只要将单片机接上时钟电路和复位电路即可MCS-51单片机由CPU、存储器和I/O三部分组成CPU是指&#xff1a;运算器和控制器 “PC CPU 3BUS RAM I/O” 在执行指令过程中&#xff…

财富池指标公式--通达信免费指标公式源码合集--第四期

久等了&#xff0c;今天这期通达信免费指标公式合集如约而至&#xff0c;依旧是三个不同功能的技术指标&#xff0c;看看有没有你正在找的吧&#xff01; 一、通达信背离出黑马指标&#xff0c;背离趋势分析指标源码 ​ ​具体信号说明&#xff1a; 1、出现底背离为买入信号…

计算机视觉——基本矩阵的计算

最近在上研究生的课程《计算机视觉》&#xff0c;完成了老师布置的大作业&#xff0c;结合我看《计算机视觉中的多视图几何》的一些感悟和收获完成此篇博客。在学习的过程中我发现很多算法并没有开源&#xff0c;或者版本太落后难以执行&#xff0c;因此想通过这篇博客将一些算…

ELK及ELFK排错

目录 一、ELK及ELFK排错思路 1.1filebeat侧排查 1.2logstash侧排查 1.3ES、kibana侧问题 一、ELK及ELFK排错思路 1.1filebeat侧排查 第一步&#xff1a;排查filebeat上的配置文件有没有写错&#xff0c;filebeat的配置文件是yml文件&#xff0c;一定要注意格式。 第二步…

WebKit内核游览器

WebKit内核游览器 基础概念游览器引擎Chromium 浏览器架构Webkit 资源加载这里就不得不提到http超文本传输协议这个概念了&#xff1a; 游览器多线程HTML 解析总结 基础概念 百度百科介绍 WebKit 是一个开源的浏览器引擎&#xff0c;与之相对应的引擎有Gecko&#xff08;Mozil…

初识ansible核心模块

目录 1、ansible模块 1.1 ansible常用模块 1.2 ansible-doc -l 列出当前anisble服务所支持的所有模块信息&#xff0c;按q退出 1.3 ansible-doc 模块名称 随机查看一个模块信息 2、运行临时命令 2.1 ansible命令常用的语法格式 3、常用模块详解与配置实例 3.1命令与…