Django rest_frameword 之项目流程
后端开发软件目录规范

一.Model
from django.db import models
# Create your models here.
# 多表的设计
# 图书 作者 出版社 作者详情表
# 基表的创建主要是我们的字段都有共同的字段抽离
class BaseModel(models.Model):
# 相同的字段
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True)
# 在建基表的时候要设置 abs 来声明基表,作为基表的model 不能再数据库中行成对应的表
class Meta:
abstract = True
class Book(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
img = models.ImageField(upload_to='img', default='img/default.jpg/')
# 外键字段的建表规则健在查询频率少的那张表 效率的问题
# 多对对外键健在那张表都可以
authors = models.ManyToManyField(to='Author',
db_constraint=False,
related_name='books')
publisher = models.ForeignKey(
to='Publish',
related_name='books', # 反向查字典的关键字publish_obj.books就能访问改出版社的所有书籍
on_delete=models.DO_NOTHING,
db_constraint=False)
class Meta:
db_table = 'book'
verbose_name = '书籍表'
verbose_name_plural = verbose_name
@property
def author_list(self):
# 查表 作者有多个值的
return self.authors.values('name', 'age','detail__addr','detail__phone').all()
@property
def publish_name(self):
# 正向按字段
return self.publisher.name
def __str__(self):
return "<%s>" % self.name
class Author(BaseModel):
name = models.CharField(max_length=32)
age = models.IntegerField()
class Meta:
db_table = 'author'
verbose_name = '作者表'
verbose_name_plural = verbose_name
def __str__(self):
return "%s" % self.name
class Publish(BaseModel):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
class Meta:
db_table = 'publish'
verbose_name = '出版社表'
verbose_name_plural = verbose_name
def __str__(self):
return "%s" % self.name
class AuthorDetail(BaseModel):
addr = models.CharField(max_length=32)
phone = models.CharField(max_length=11, null=True)
# 外键字段一对多还是建立多方
# 一对一就健在查询评率低的一方
# 一对一的cascade是同步的进行同删同减
author_detail = models.OneToOneField(to='Author',
db_constraint=False,
related_name='detail',
on_delete=models.CASCADE)
class Meta:
db_table = 'author_detail'
verbose_name = '详情表'
verbose_name_plural = verbose_name
def __str__(self):
return "%s" % self.author_detail.name
api 或者项目名下的__init__
import pymysql pymysql.install_as_MySQLdb()
二.settings
数据库和全局文件的配置 图片的暴露接口
"""
Django settings for day71_djproj project.
Generated by 'django-admin startproject' using Django 1.11.11.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^zqxsy^v6z)!9klipb^^3@=txceu7^b4!-rsp#8r55&_u^p11h'
# 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',
'api.apps.ApiConfig',
'rest_framework'
]
MIDDLEWARE = [
'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',
]
ROOT_URLCONF = 'day71_djproj.urls'
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 = 'day71_djproj.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day71_dj',
'USER': "root",
',
'HOST':"127.0.0.1",
'PORT': 3306
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/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',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
# 图片
MEDIA_URL = '/media/'
# 图片的更目录的配置
MEDIA_ROOT = os.path.join(BASE_DIR,'/media/')
# 我们还要配置解析的全局配置文件 如果想要配置局部的就要在我们自己的类函数下进行配置 方法
# 配置响应的全局文件
# 配置自定义的异常文件的全局的配置
# 自定义drf配置爱-全局响应配置
REST_FRAMEWORK = {
# drf提供的渲染类
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
# drf提供类解析的数据包的格式 请求格式 再取全局进行配置 全局 进而进行局部的的设置
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
],
# 全局配置异常模块 自定有异常模块
'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}
准备事项配置好后 model 表的迁移命令
(1)
D:\day71_djproj>python manage.py makemigrations
(2)python manage.py migrate
或者快捷键

三.admin
注册超级用户 createsuperuser()
将我们的model 模型表一一注册到我们的admin 中>>> 数据的新增 (方便测试)
from django.contrib import admin from api import models # Register your models here. admin.site.register(models.Author) admin.site.register(models.Book) admin.site.register(models.AuthorDetail) admin.site.register(models.Publish)
四.URL 路由的匹配
(1)总路由 >>>实现陆游的分发
from django.conf.urls import url, include
from django.contrib import admin
# from django.conf.urls import url
# 资源暴露给外部 必须配置在全局的
# 渲染图片 接口暴露给外部\
from day71_djproj import settings
from django.views.static import serve
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('api.urls')),
url(r'^media/(?P<path>.*)', serve, {'document_root':settings.MEDIA_ROOT}),
]
(2)项目api下的路由
from django.conf.urls import url
from api import views
# 路由模块:为标准的viweset接口提供路径的简写方式
from django.conf.urls import include
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
# 路径对象进注册
router.register('v6/books',views.BookModelViewSet)
urlpatterns = [
url(r'^books/$',views.V2Book.as_view()),
url(r'^books/(?P<pk>.*)/$',views.V2Book.as_view()),
url(r"^v1/books/$",views.BookApIView.as_view()),
url(r"^v1/books/(?P<pk>.*)/$", views.BookApIView.as_view()),
url(r"^v2/books/$", views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
url(r"^v3/books/$", views.BookMixinGenericAPIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
url(r"^v4/books/$", views.BookListCreateAPIView.as_view()),
url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreateAPIView.as_view()),
url(r"^v5/books/$", views.BookGenericViewSet.as_view({"get": "my_get_list"})),
url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({"get": "my_get_obj"})),
url(r"^vv/books/$", views.MyRequest.as_view()),
url(r'^vv/books/(?P<pk>.*)/$', views.MyRequest.as_view()),
url(r'^v7/books/$',views.BookModelViewSet.as_view({"get":'list','post':'create'})),
url(r'^v7/books/(?P<pk>.*)/$',views.BookModelViewSet.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'})),
# 在下面进行分发应用匹配
url(r'^',include(router.urls))
]
五.视图函数
from django.shortcuts import render
from . import serializers
from api import models
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from utils.response import APIResponse
class V2Book(APIView):
# 单查
# 群查
def get(self, request, *args, **kwargs):
# print(request.query_params,12312)
pk = kwargs.get('pk')
if pk:
try:
book_obj = models.Book.objects.get(pk=pk, is_delete=False)
print(book_obj, type(book_obj), 3212)
book_data = serializers.BookModelSerializer(book_obj).data
# print(book_data,type(book_data),123)
return Response({
'status': 1,
'msg': 'ok',
'results': book_data
})
except:
return Response({
"status": 0,
'img': "数据有误"
})
else:
book_query = models.Book.objects.filter(is_delete=False).all()
book_data = serializers.BookModelSerializer(book_query, many=True).data
return Response({
'status': 1,
'msg': 'ok',
'results': book_data
})
# 反序列化的 通过序列化组件
# user_ser = serializer
def post(self, request, *args, **kwargs):
# 单增数据是与model对应的字典 获取的数据的格式和类型的检验
request_data = request.data
print(request_data)
# if not isinstance(request_data,dict) or request_data == {}:
# return Response({
# 'status': 1,
# 'msg': '数据有误',
#
# })
# else:
# 单增
if isinstance(request_data, dict) and request_data != {}:
many = False
book_data = serializers.BookModelSerializer(data=request_data, many=many) # 进行反序列化的对象赋值
# 当前视图异常是 立即出发报错异常的进行返回到前端
book_data.is_valid(raise_exception=True) # 进行数据的检验
data_result = book_data.save()
return Response({
'status': 1,
'msg': 'ok',
'results': serializers.BookModelSerializer(data_result).data # 反序列化
})
elif isinstance(request_data, list) and request_data != []: # 是多个值的话 同时新增多个对象
many = True
book_data = serializers.BookModelSerializer(data=request_data, many=many) # 反序列化 再存
book_data.is_valid(raise_exception=True) # 进行数据的检验
# ???
data_result = book_data.save()
return Response({
'status': 1,
'msg': 'ok',
'results': serializers.BookModelSerializer(data_result, many=many).data # 反序列化
})
else:
return Response({
'status': 0,
'msg': '数据格式有误'
})
# 获取数据
# 全增
def delete(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
# pk__in 符合下面的要求
pks = [pk]
else:
pks = request.data.get('pks')
if models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True):
# 直接返回
return Response({
'status': 1,
'msg': '删除成功'
})
else:
return Response({
'status': 0,
'msg': '删除未成功'
})
def put(self, request, *args, **kwargs):
# 单 整体修改
# 序列化的是对象
pk = kwargs.get('pk')
book_obj = models.Book.objects.filter(pk=pk).first()
# 反序列化 数据
request_data = request.data
# 反序列化的对数据进行修改的三件事 1.数据是改谁的 2.将数据进行data 封装 3.完序列化后的数据的检验
# 反序列化的是传的对象的 和值
book_ser = serializers.BookModelSerializer(instance=book_obj, data=request_data, )
# 反序列化传数据 还需要修改的对象
# 检验
book_ser.is_valid(raise_exception=True)
# 修改入库
result_obj = book_ser.save() # 修改入库
return Response({
'status': 1,
'msg': '修改成功',
# 返回的 是序列化对象 传入的是save() 返回的对象
'results': serializers.BookModelSerializer(result_obj).data
})
# 进行单改和全改的patch()
# 单体pk = [1,]
# 多改pk=[1,2,3]
def patch(self, request, *args, **kwargs):
pk = kwargs.get("pk")
request_data = request.data
# 单改
if pk and isinstance(request_data, dict):
pks = [pk, ]
request_data = [request_data, ]
# 群改
elif not pk and isinstance(request_data, list):
pks = []
#
for data in request_data:
# 将每个数据中的字典进行删除(本质是返回键)
pk = data.pop('pk', None)
if pk:
pks.append(pk)
else:
return Response({
'status': 0,
'msg': '数据有误'
})
else:
return Response({
"status": 0,
'msg': "数据有误"
})
# 将上面的单改和群对象改进行逻辑业务处理
# 我们需要处理的是pks中 and健值绑定的没有数据的pks 进行删除
# 将合理的数据进保存
objs = []
new_data = []
for index, pk in enumerate(pks):
try:
# 存储合理的数据进行修改
obj = models.Book.objects.get(pk=pk, is_delete=False) # BUG
objs.append(obj)
# 将对应上的数据保存
new_data.append(request_data[index])
except:
# 继续循环 循环结束继续结束
continue
# 统一的逻辑
book_ser = serializers.BookModelSerializer(instance=objs, data=new_data, partial=True, many=True)
# 校验
book_ser.is_valid(raise_exception=True)
print(book_ser, 123)
book_obj = book_ser.save()
print(book_obj, 555)
# 返回
return Response({
'status': 1,
'msg': '修改成功',
# 序列化和反序列化只要有多个必须是many = TRUE
'results': serializers.BookModelSerializer(book_obj, many=True).data
})
# 重写response() 响应方法
class BookApIView(APIView):
def get(self, *args, **kwargs):
book_query = models.Book.objects.filter(is_delete=False).all()
book_ser = serializers.BookModelSerializer(book_query, many=True)
# print(book_ser)
book_data = book_ser.data # 数据是存放在data 中的
# print(book_data)
# 返回数据我们用封装号的
return APIResponse(results=book_data)
# Genseric 类
from rest_framework.generics import GenericAPIView
class BookGenericAPIView(GenericAPIView):
# 因为我们继承的是GenericAPIView >>> 继承APIView
# queryset = None 和serializer = None 初始值为空时需要我们进行重写的
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
# 单查 pk get的方法
lookup_field = 'pk'
# def get(self, request, *args, **kwargs):
# book_query = self.get_object()
# print(book_query, 55)
# book_ser = self.get_serializer(book_query)
# book_data = book_ser.data
# return APIResponse(results=book_data)
# 群查
def get(self, request, *args, **kwargs):
book_query = self.get_queryset()
book_ser = self.get_serializer(book_query,many=True) # 这里加上many=True
book_data = book_ser.data
return APIResponse(results=book_data)
"""
# 1)mixins有五个工具类文件,一共提供了五个工具类,六个工具方法:单查、群查、单增、单删、单整体改、单局部改
# 2)继承工具类可以简化请求函数的实现体,但是必须继承GenericAPIView,需要GenericAPIView类提供的几个类属性和方法(见上方GenericAPIView基类知识点)
# 3)工具类的工具方法返回值都是Response类型对象,如果要格式化数据格式再返回给前台,可以通过 response.data 拿到工具方法返回的Response类型对象的响应数据
"""
# mixins 有五大工具六大方法
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin
class BookMixinGenericAPIView(ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,GenericAPIView):
# 先获取对象
queryset = models.Book.objects.filter(is_delete=False)
# 重写序列化
serializer_class = serializers.BookModelSerializer
# get 查询
def get(self,request,*args, **kwargs):
# mixins 中的单查 pk
if 'pk' in kwargs:
response = self.retrieve(request,*args,**kwargs)
else:
# mixins提供的list方法的响应对象是Response,想将该对象格式化为APIResponse
response = self.list(request, *args, **kwargs)
# 数据都是封装在response
return APIResponse(results=response.data)
# 单增post 多增的操作
def post(self, request, *args, **kwargs):
response = self.create(request, *args, **kwargs)
return APIResponse(results=response.data)
# =更新put
# 注意必须在pk = 22 有值的情况 也必须是在url 中拼接pk 才能进行目前的修改
def put(self,request, *args, **kwargs):
response = self.update(request, *args, **kwargs)
return APIResponse(results=response.data)
# patch修改 也会需要 pk url 中拼接
def patch(self,request, *args, **kwargs):
response = self.update(request, *args, **kwargs)
return APIResponse(results=response.data)
# 工具视图
"""
# 1)工具视图都是GenericAPIView的子类,且不同的子类继承了不听的工具类,重写了请求方法
# 2)工具视图的功能如果直接可以满足需求,只需要继承工具视图,提供queryset与serializer_class即可
"""
# 群查 局部更新
from rest_framework.generics import ListCreateAPIView,UpdateAPIView
class BookListCreateAPIView(ListCreateAPIView, UpdateAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
# 视图集..set
"""
(1)优先继承ViewSetMixin 类 再继承一个视图类(GenericViewSet 和APIView)
(2)ViewSetMixin提供重写ad_view() 方法 ,继承视图集的属兔类,-匹配路由调用da_view() 必须出入对饮的映射关系as_view("get":"my_get_list")
"""
from rest_framework.viewsets import GenericViewSet # 视图集中导入视图类
from rest_framework import mixins # 工具类
class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
# 群查
def my_get_list(self,request,*args, **kwargs):
return self.list(request, *args, **kwargs)
# 单查
def my_get_obj(self, request,*args, **kwargs):
return self.retrieve(request, *args, **kwargs)
class MyRequest(APIView):
def post(self, request, *args, **kwargs):
request_data = request.data
# book_ser 序列化数据对象
book_data = serializers.BookModelSerializer(data=request_data, many=False, context={"request": request})
# 进行数据的检验
book_data.is_valid(raise_exception=True)
result_data = book_data.save()
return APIResponse(results=result_data) # 直接封装 create() 的话要进行many = True
# 拥有就打接口:单查/群查/单增/ 单删/单整体改/单局部改
# 补充:一般肯定需要我们重写destroy 方法
"""
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet): # 继承这个主要是让他遵循我们自己写的as_view({"get":"list",'patch':"partial_update",'put':"update","post":"create", "destroy":'destroy'})
"""
from rest_framework.viewsets import ModelViewSet
class BookModelViewSet(ModelViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
"""
as_view({"get":'list','post':'create'})
get >>>list 群查 post >>> 新增
as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'}
get >>>retrieve 单查 提供pk在url put >>> partial = False不能进单个字段的修改 而是整体字段的更新
patch >>>> partial_update 默认partial = True,
"""
# 一般我们删除的不是真正的数据 而是将他的bOOL 改为1 /获取是Treu
# 除了删除需要我们自己写 因为 特会将正真的数据进行删除肯定不合理 所以我们自己写优先走我们自己的
def destroy(self, request, *args, **kwargs):
instance = self.get_object() # 单删 实列化对象
if not instance: # 改实例对象不存在
return APIResponse(0, '删除失败')
instance.is_delete = True
instance.save()
return APIResponse(1,'删除成功')
六.serializer文件:对象 序列化 钩子函数
from rest_framework.serializers import ModelSerializer,SerializerMethodField
from rest_framework.serializers import ListSerializer
from rest_framework.exceptions import ValidationError
from . import models
# 重写我们update() 方法
# 重点将我们ListSerializer()
class BookListSerializer(ListSerializer):
def update(self, instance, validated_data):
print(instance,111) # [<Book: <东游记9988>>, <Book: <西游记999>>, <Book: <南游记>>]
print(validated_data,2222)
# [{'name': '东游记88', 'price': Decimal('66.66')}, {'name': '西游记999',
# 'price': Decimal('77.88')}, {'name': '南游记', 'price': Decimal('8.88')}]
# 获取里面的所有数据
print(self.child,12312312)
for index, obj in enumerate(instance):
# 获取对象的索引和下标
self.child.update(obj,validated_data[index])
return instance # 返回对象
class BookModelSerializer(ModelSerializer):
class Meta:
model = models.Book
# 映射
fields = ('name','price', 'img','author_list', 'publish_name','publisher','authors')
extra_kwargs = {
'name':{
'required':True,
'min_length':3,
'error_messages':{
'required':'必填字段',
'min_length':'不能少于3位数字'
}
},
'publisher':{
'write_only':True,
},
'authors':{
'write_only': True
},
'img':{
'read_only':True,
},
'author_list':{
'read_only':True
},
'publish_name':{
'read_only':True
}
}
# patch()方法是用save()
# 方法进行数据的更新 但是没有进行update()方法的封装 需要我们自己 重写update() 方法
list_serializer_class = BookListSerializer
# 局部勾子和全局钩子
def validate_name(self,value):
# 书名不能有'si'字符
print(self.context,1111)
if 'k' in value: # ???
raise ValidationError('该k书不能出版')
return value
# 全局钩子
def validate(self, attrs):
publisher = attrs.get('publisher')
name = attrs.get('name')
if models.Book.objects.filter(name=name,publisher=publisher):
raise ValidationError({'book':'该书已经存在'})
return attrs
七.Media 媒体文件

八. exception自定义用异常文件
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
def exception_handler(exc, context):
# drf的exception_handler做基础处理
response = drf_exception_handler(exc, context)
# 为空,自定义二次处理
if response is None:
print('%s - %s - %s' % (context['view'], context['request'].method, exc))
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response
九.utils文件 自定义响应的数据格式 以及我们的自定义分页器

# 我们自定义from rest_framework.response import Response
class APIResponse(Response): def __init__(self, data_status=1,data_msg='ok', results=None,http_status=None, headers=None,exception=False,*kwargs): # 我们需要返回的值 # data的初始信息: data = { 'status':data_status, 'msg':data_msg, } # data的响应数据体 # results 响应可能是False 0等数据 这些数据在我们设计的方法下是不合法的所以要进行过滤 if results is not None: data['results'] = results # 将请求后的字典内容进行更新 有则 data.update(kwargs) super().__init__(data=data,status=http_status,headers=headers,exception=exception)
待更新........
Django rest_frameword 之项目流程的更多相关文章
- django搭建简单开发项目流程(一)
1 搭建环境 sudo apt-get install python3-pip 安装pip3 sudo pip3 install virtualenv 安装虚拟环境 virtualenv -p pyt ...
- web理论知识--网页访问过程(附有Django的web项目访问流程)
当我们闲暇之余想上网看看新闻,或者看个电影,通常的操作是:打开电脑.打开浏览器.输入网址.浏览页面信息.点击自己感兴趣的连接......那么有没有想过,这些网页从哪里来的?过程中计算机又做了什么事情了 ...
- Django 小实例S1 简易学生选课管理系统 1 项目流程梳理与数据库设计
Django 小实例S1 简易学生选课管理系统 第1章--项目流程梳理与数据库设计 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 1 项目流程梳理 ...
- Django——博客项目
博客项目 目前的目标是构建一个基于Django的前后端完整的博客系统,首先对项目流程整理如下: 1. 分析需求 1.1. 基于用户认证组件和Ajax实现登录验证 图形验证码核心代码: 模板: < ...
- BBS+Blog项目流程及补充知识点
项目流程: 1. 产品需求 (1)基于用户认证组件和Ajax实现登陆验证(图片验证码) (2)基于forms组件和Ajax实现注册功能 (3)设计系统首页(文章列表渲染) (4)设计个人站点页面 (5 ...
- Django Rest framework实现流程
目录 一 什么是restful架构 二 Django REST framework简介 三 Django REST framework原理 四 Django REST framework源码流程 五 ...
- Django运行方式及处理流程总结(转发)
之前在网上看过一些介绍Django处理请求的流程和Django源码结构的文章,觉得了解一下这些内容对开发Django项目还是很有帮助的.所以,我按照自己的逻辑总结了一下Django项目的运行方式和对R ...
- iOS开发项目之一 [ 项目流程]
项目流程 *人员配置 *客户端(iOS工程师,Android工程师) *前端 h5 *后台人员(php,java,net) *提供接口(请求地址.请求参数,请求方式,接口文档) *UI UE * 效果 ...
- ng机器学习视频笔记(十六) ——从图像处理谈机器学习项目流程
ng机器学习视频笔记(十六) --从图像处理谈机器学习项目流程 (转载请附上本文链接--linhxx) 一.概述 这里简单讨论图像处理的机器学习过程,主要讨论的是机器学习的项目流程.采用的业务示例是O ...
随机推荐
- 2.Python环境搭建Window、mac、linux
1.Windows安装Python详解 使用任何高级编程语言都需要有一个自己的编程环境,Python 也不例外.只要使用 Python,就必须要配置 Python 的开发和运行环境. Python 本 ...
- 几种常见的CSS布局
本文概要 本文将介绍如下几种常见的布局: 其中实现三栏布局有多种方式,本文着重介绍圣杯布局和双飞翼布局.另外几种可以猛戳实现三栏布局的几种方法 一.单列布局 常见的单列布局有两种: header,co ...
- ES排序值相同顺序随机的问题
ES排序值相同顺序随机的问题 code[class*="language-"] { padding: .1em; border-radius: .3em; white-space: ...
- jQuery file upload里面的_create的调用和_initEventHandlers的调用
首先是jquery.ui.widget.js中_createWidget方法内部调用 this._create(); this._trigger( "create", null, ...
- KVM 常用命令
显示虚拟机 virsh list --all 停止虚拟机 virsh destroy <name> 启动虚拟机 virsh start <name> 删除虚拟机 virsh u ...
- SpringMVC中mvc:view-controller的使用
1.重定向 <mvc:view-controller path="/" view-name="redirect:/admin/index"/> 即如 ...
- leetcode 342. 4的幂(python)
1. 题目描述 给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方. 示例 1: 输入: 16输出: true示例 2: 输入: 5输出: false 2. 思路 参考: ...
- BFC块级格式
BFC块级格式上下文,独立的一个渲染区域 1.同一个BFC的两个相邻盒子间的margin会重叠(垂直方向): 2.BFC内部的盒子在垂直方向上会一个接一个的放置: 3.每个子元素的左外边距与包含块的左 ...
- Linux_Grub2、系统启动流程_RHEL7
目录 目录 前言 系统启动流程 控制RHEL7启动过程 编辑gurbcfg RHEL7启动级别 修改系统运行级别 RHEL7破密码步骤 grup2加密防止破密码 initramfs文件 前言 RHEL ...
- Jmeter之保存响应到文件
在jmeter中使用保存响应到文件 ------适用于非GUI模式执行脚本时,无法查看报错的信息. 1.添加组件: 2.各个配置项说明: (1.名称:即组件在整个测试计划中的名称显示,建议设置为用意义 ...