一。事务的隔离级别。
mysql的默认数据库级别是可重复读,一般的应用使用的是读已提交
http://www.zsythink.net/archives/1233/
1. Read UnCommitted(读未提交)
最低的隔离级别。一个事务可以读取另一个事务并未提交的更新结果。
2. Read Committed(读提交)
大部分数据库采用的默认隔离级别。一个事务的更新操作结果只有在该事务提交之后,另一个事务才可以的读取到同一笔数据更新后的结果。
3. Repeatable Read(重复读)
mysql的默认级别。整个事务过程中,对同一笔数据的读取结果是相同的,不管其他事务是否在对共享数据进行更新,也不管更新提交与否。
4. Serializable(序列化)
最高隔离级别。所有事务操作依次顺序执行。注意这会导致并发度下降,性能最差。通常会用其他并发级别加上相应的并发锁机制来取代它。
1.脏读。
当两个事务对数据进行操作时,事务A读取了一些数据之后,对其进行修改,但是还未提交,事务b对该数据进行读取的时候读取的是事务a修改后的数据,这个数据就是一个脏数据,如果数据a对该数据进行回滚,就会报错。
2.不可重复读
当事务A对一些数据进行读取的时候,事务B也对该数据进行了读取,并修改,当事务A再次对其进行读取的时候,就会发现数据不对,就是不可重复读。即数据不重复。
3。幻读。
在重复读的隔离级别下,数据是不能被修改的,但是可以被提交,所以当事务A对影响行数据进行读取的时候,事务b添加了一项数据,事务A再次读取的时候就会发现多了一条数据,就像出现幻觉一样。
处理方法:
1.悲观锁。
当事务处理数据的时候。默认所有的数据会被其他数据操作,所以加上锁,不开放任何权限(包括查的权限),保证所有数据都处理完再开放锁。
2。乐观锁,
当处理事务的时候,默认所有的数据不会被其他数据,再提交数据之前再进行判断库中的数据是否和一开始读的数据相同(需要再可重复读的级别下,再事务过程中,保证识别到其他操作的提交数据)。
在处理数据时,后提交的操作会时最终的数据。
二。celery
当订单提交完毕之后,用户不会马上支付,就会调用celery分配异步任务,将该任务延时一定时间,将其回滚到一开始的状态。
项目详情。
comment
def get_level(data): data_list=[] for item in data: if item['parent_id']==0: item['level']=0 else: item['level']=1 data_list.append(item) return data_list data=[ {"cat_id":1,"name":"北京","parent_id":0}, {"cat_id":2,"name":"上海","parent_id":0}, {"cat_id":3,"name":"沙河","parent_id":1}, {"cat_id":4,"name":"sb镇","parent_id":3}, {"cat_id":5,"name":"昌平","parent_id":1}, {"cat_id":6,"name":"青浦","parent_id":2}, ] def get_tree(data): lists=[] tree={} for i in data: tree[i['cat_id']]=i for item in data: if not item['parent_id']: lists.append(tree[item['cat_id']]) else: if "children" not in tree[item['parent_id']]: tree[item['parent_id']]['children']=[] tree[item['parent_id']]['children'].append(tree[item['cat_id']]) return lists print(get_tree(data)) res=[] def get_son(data,level=0,parent_id=0,is_clear=True): if is_clear: res.clear() for item in data: if item['parent_id']==parent_id: item['level']=level res.append(item) get_son(data,level=level+1,parent_id=item['cat_id'],is_clear=False) return res # print(get_son(data)) # son=get_son(data) # for i in son: # print("-"*i['level']+i['name']) # 1北京 0 # 2-海淀1 # 4--sb镇2 # -昌平 # 3 上海 0 # -青浦 # --徐泾镇 # -闵行 res_id=[] def get_son_id(data,parent_id=0,is_clear=True): if is_clear: res_id.clear() if parent_id : res_id.append(parent_id) for item in data: if item['parent_id']==parent_id: res_id.append(item['cat_id']) get_son_id(data,parent_id=item['cat_id'],is_clear=False) return res_id # print(get_son_id(data,1)) import time ,random def get_order_id(): st="012345679qwertyui" order_id=str(time.strftime("%Y%m%d%h%M%S"))+"".join(random.sample(st,5)) return order_id from datetime import datetime def add_task(order_id,seconds=5): from pro_celery.celery import del_order ctime = datetime.now() utc_ctime = datetime.utcfromtimestamp(ctime.timestamp()) from datetime import timedelta time_delay = timedelta(seconds=seconds) task_time = utc_ctime + time_delay result = del_order.apply_async(args=[order_id, ], eta=task_time)
my_ser
from rest_framework import serializers from app01 import models class Banner_ser(serializers.ModelSerializer): image_url=serializers.ImageField(source="image.image_url") product_id=serializers.IntegerField(source="product.product_id") class Meta: model=models.Banner fields="__all__"
from rest_framework import serializers from app01 import models class Category_ser(serializers.ModelSerializer): image_url=serializers.ImageField(source="image.image_url") parent_id=serializers.SerializerMethodField() def get_parent_id(self,obj): if obj.parent_id is None: return 0 else: return obj.parent_id class Meta: model=models.Category fields="__all__"
from rest_framework import serializers from app01 import models class Goods_ser(serializers.ModelSerializer): image_url=serializers.ImageField(source="image.image_url") stock=serializers.IntegerField(source="stock.quantity") class Meta: model=models.Product fields="__all__"
Pay
import time from app01.wx import settings class Wxpay: def pay(self,order_data): self.order_id = order_data["order_id"] self.open_id = order_data['open_id'] self.ip = order_data['ip'] data_body = self.get_body_data() import requests url = "https://api.mch.weixin.qq.com/pay/unifiedorder" response = requests.post(url, data_body.encode("utf-8"), headers={'content-type': "application/xml"}) res_dict = self.xml_to_dic(response.content) timeStamp = str(int(time.time())) paySign = self.get_pay_sign(res_dict, timeStamp) data_dic = { 'timeStamp': timeStamp, 'nonceStr': res_dict['nonce_str'], 'package': f"prepay_id={res_dict['prepay_id']}", 'signType': 'MD5', "paySign": paySign, } return data_dic def get_pay_sign(self, res_dict, timeStamp): data_dic = { 'appId': res_dict['appid'], 'timeStamp': timeStamp, 'nonceStr': res_dict['nonce_str'], 'package': f"prepay_id={res_dict['prepay_id']}", "signType": "MD5" } sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)]) sign_str = f"{sign_str}&key={settings.pay_apikey}" import hashlib md5 = hashlib.md5() md5.update(sign_str.encode("utf-8")) sign = md5.hexdigest() return sign.upper() def xml_to_dic(self, xml_data): import xml.etree.ElementTree as ET ''' xml to dict :param xml_data: :return: ''' xml_dict = {} root = ET.fromstring(xml_data) for child in root: xml_dict[child.tag] = child.text return xml_dict def get_random(self): import random data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP" nonce_str = "".join(random.sample(data, 30)) return nonce_str def get_sign(self): data_dic = { "nonce_str": self.nonce_str, "out_trade_no": self.out_trade_no, "spbill_create_ip": self.spbill_create_ip, "notify_url": self.notify_url, "openid": self.open_id, "body": self.body, "trade_type": "JSAPI", "appid": self.appid, "total_fee": "1", "mch_id": self.mch_id } sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)]) sign_str = f"{sign_str}&key={settings.pay_apikey}" import hashlib md5 = hashlib.md5() md5.update(sign_str.encode("utf-8")) sign = md5.hexdigest() return sign.upper() def get_body_data(self): self.appid = settings.AppId # openid=self.open_id self.mch_id = str(settings.pay_mchid) self.nonce_str = self.get_random() self.out_trade_no = self.order_id self.spbill_create_ip = self.ip self.notify_url = "https://www.test.com" self.body = "lzx" self.sign = self.get_sign() body_data = f""" <xml> <appid>{self.appid}</appid> <mch_id>{self.mch_id}</mch_id> <nonce_str>{self.nonce_str}</nonce_str> <sign>{self.sign}</sign> <body>{self.body}</body> <out_trade_no>{self.out_trade_no}</out_trade_no> <total_fee>1</total_fee> <spbill_create_ip>{ self.spbill_create_ip}</spbill_create_ip> <notify_url>{self.notify_url}</notify_url> <openid>{self.open_id}</openid> <trade_type>JSAPI</trade_type> </xml>""" return body_data
views
from rest_framework.views import APIView from rest_framework.response import Response from app01 import models from app01.my_ser import Banner_ser class List(APIView): def post(self,request): data = models.Banner.objects.filter(is_show=True).order_by("-w_order") data = Banner_ser.Banner_ser(instance=data,many=True,context={"request":request}).data return Response({ "code":200, "msg":"ok", "data":data })
from rest_framework.views import APIView from rest_framework.response import Response from app01 import models from app01.my_ser import Category_ser from app01.comment import func class All(APIView): def post(self,request): data=models.Category.objects.filter(is_show=True) data=Category_ser.Category_ser(instance=data,many=True,context={"request":request}).data data=func.get_son(data) return Response({ "code":200, "msg":"ok", "data":data })
from rest_framework.views import APIView from rest_framework.response import Response from app01.my_ser import Goods_ser from app01 import models from app01.my_ser import Category_ser,Goods_ser from app01.comment import func class HotGoods(APIView): def post(self,request): data=models.Product.objects.filter(disabled=True).order_by("-buy_count","-w_order") data=Goods_ser.Goods_ser(instance=data,many=True,context={"request":request}).data return Response({"code":200,"msg":"ok","data":data}) class List(APIView): def post(self,request): param=request.data if param.get('category_id'): data=models.Category.objects.filter(is_show=True) data=Category_ser.Category_ser(instance=data,many=True,context={"request":request}).data all_id=func.get_son_id(data,param['category_id']) data=models.Product.objects.filter(disabled=True,cat_id__in=all_id).order_by("-w_order") data = Goods_ser.Goods_ser(instance=data, many=True, context={"request": request}).data return Response({"code": 200, "msg": "ok", "data": data}) else: return Response({"code": 201, "msg":"缺少参数" }) class Detail(APIView): def post(self,request): param=request.data if param.get("id"): data = models.Product.objects.filter(disabled=True,product_id=param.get("id")).first() if data: data = Goods_ser.Goods_ser(instance=data, many=False, context={"request": request}).data print(data) return Response({"code": 200, "msg": "ok", "data": data}) else: return Response({"code": 201, "msg": "没有该商品"})
import importlib from rest_framework.views import APIView from rest_framework.response import Response from django.core.cache import cache from app01 import models from app01.comment import func import hashlib, time from django.db import transaction from django import forms class OrderForm(forms.Form): phone = forms.CharField( error_messages={ "required": "手机号不能为空" }, # 调用Form组件中的验证器来校验手机号 # validators=[RegexValidator(r'1[1-9][0-9]{9}', '手机号格式不正确')], ) token = forms.CharField(error_messages={ "required": "token不能为空" }) province = forms.CharField(error_messages={ "required": "省份不能为空" }) city = forms.CharField(error_messages={ "required": "城市不能为空" }) county = forms.CharField(error_messages={ "required": "县/区不能为空" }) address = forms.CharField(error_messages={ "required": "详细地址不能为空" }) name = forms.CharField(error_messages={ "required": "姓名不能为空" }) class Creat(APIView): @transaction.atomic def post(self, request): param = request.data form_obj = OrderForm(param) if form_obj.is_valid() and param['buy_list']: if request.META.get("HTTP_X_FORWARDED_FOR"): host_ip = request.META["HTTP_X_FROWARDED_FOR"] else: host_ip = request.META["REMOTE_ADDR"] user_cache = cache.get(param['token']) if user_cache: openid = user_cache.split("&")[0] user_data = models.Wxuser.objects.filter(openid=openid).first() order_data = {"consignee_mobile": param['phone'], 'consignee_name': param['name'], 'wxuser_id': user_data.id, "memo": param['remark'], "consignee_area": f"{param['province']},{param['city']},{param['county']}", "consignee_address": param['address'], } buy_list = param['buy_list'] goods_key = list(buy_list.keys()) all_product = models.Product.objects.filter(product_id__in=goods_key) order_data['order_id'] = func.get_order_id() order_data['order_total'] = 0 order_data['quantity'] = 0 sid = transaction.savepoint() for product in all_product: product.product_id = str(product.product_id) order_data['order_total'] += product.price * buy_list[product.product_id] order_data['quantity'] += buy_list[product.product_id] # 创建子订单 for i in range(3): stock = product.stock.quantity new_stock = stock - buy_list[product.product_id] if new_stock < 0: transaction.rollback(sid) return Response({"code": 203, "msg": f"{product.name}库存不足"}) res = models.Stock.objects.filter(quantity=stock, stock_id=product.stock.stock_id).update( quantity=new_stock) if not res: if i == 2: transaction.rollback(sid) return Response({"code": 203, "msg": f"创建订单失败"}) else: continue else: break new_buy_count = product.buy_count + buy_list[product.product_id] models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count) order_item_data = {'order_id': order_data['order_id'], 'product_id': product.product_id, \ "name": product.name, "image": product.image, "price": product.price, \ "nums": buy_list[product.product_id], "brief": product.brief} models.Order_items.objects.create(**order_item_data) # models.Order_items.objects.create(**order_item_data) models.Order.objects.create(**order_data) pay_methon = "Wxpay" try: pay_file = importlib.import_module(f"app01.Pay.{pay_methon}") pay_class = getattr(pay_file,pay_methon) order_data['open_id'] = openid order_data['ip'] = host_ip data = pay_class().pay(order_data) except: transaction.savepoint_rollback(sid) return Response({"code": 202, "msg": "未知的支付方式"}) transaction.savepoint_commit(sid) func.add_task(order_data['order_id']) return Response({"code": 200, "msg":"ok","data":data}) else: return Response({"code": 202, "msg": "token已过期"}) else: return Response({"code": 201, "msg": "缺少参数"}) class Notity(APIView): def post(self,request,paymethon): pay_file = importlib.import_module(f"app01.Pay.{paymethon}") pay_class = getattr(pay_file, paymethon) data=pay_class().notity(request.data) if data['status']=="success": models.Order.objects.filter(order_id=data['order']).updata(pay_status=1)
from rest_framework.views import APIView from rest_framework.response import Response from django.core.cache import cache from app01 import models import hashlib,time from app01.wx import wx_Login class Login(APIView): def post(self,request): param=request.data if param.get("code"): data=wx_Login.login(param.get("code")) if data: val=data['openid']+"&"+data["session_key"] key=str(int(time.time()))+data['openid'] md5=hashlib.md5() md5.update(key.encode("utf-8")) key=md5.hexdigest() cache.set(key,val) has_user=models.Wxuser.objects.filter(openid=data['openid']).first() if not has_user: models.Wxuser.objects.create(openid=data['openid']) return Response({"code":200,"msg":"ok",'data':{"login_key":key}}) else: return Response({"code":200,"msg":"code错误"}) else: return Response({"code": 200, "msg": "缺少参数"})
wx
import xadmin from xadmin import views from app01 import models class BaseSetting(object): """xadmin的基本配置""" enable_themes = True # 开启主题切换功能 use_bootswatch = True xadmin.site.register(views.BaseAdminView, BaseSetting) class GlobalSettings(object): """xadmin的全局配置""" site_title = "商城后台" # 设置站点标题 site_footer = "饼哥有限公司" # 设置站点的页脚 menu_style = "accordion" # 设置菜单折叠 xadmin.site.register(views.CommAdminView, GlobalSettings) xadmin.site.register(models.Order_items) xadmin.site.register(models.Product) xadmin.site.register(models.Order) xadmin.site.register(models.Category) xadmin.site.register(models.Stock) xadmin.site.register(models.Images) xadmin.site.register(models.Wxuser) xadmin.site.register(models.Banner)
from django.db import models # Create your models here. ''' #banner id image_url product_id is_show w_order create_time update_time #销量最高的排前面,销量一样,权重大的在前面 #product_id id name price intor buy_count w_order (越大越前) detail image_url scort #库存 is_show catory_id create_time update_time #scort库存 id name num create_time update_time #category_id id cate_name image_url parent_id create_time update_time #imgae id imgae_url name create_time update_time #订单 order_id 商品总数量 总价格 收货地址 用户id 订单状态(是否取消) 收货人电话 收人姓名 支付 create_time update_time order_item id order_id 商品id 商品价格 num image_url create_time update_time ''' # Create your models here. class Wxuser(models.Model): id = models.AutoField(primary_key=True) openid=models.CharField(max_length=255) name = models.CharField(max_length=50) avatar = models.CharField(max_length=200) language = models.CharField(max_length=50) province = models.CharField(max_length=50) city = models.CharField(max_length=50) country = models.CharField(max_length=50) gender = models.CharField(max_length=50), creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.openid class Category(models.Model): cat_id=models.AutoField(primary_key=True) category_name=models.CharField(max_length=50) parent=models.ForeignKey(to='Category', to_field='cat_id', related_name="Category", on_delete=models.CASCADE, db_constraint=False,blank=True,null=True) p_order=models.IntegerField(default=0) is_show =models.BooleanField(default=1) image = models.OneToOneField(to='Images', to_field='image_id', on_delete=models.CASCADE, db_constraint=False,null=True) creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.category_name class Images(models.Model): image_id=models.AutoField(primary_key=True) name=models.CharField(max_length=30,default="0") image_url=models.ImageField(upload_to="") creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Product(models.Model): product_id=models.AutoField(primary_key=True) name=models.CharField(max_length=200) price=models.DecimalField(max_digits=10, decimal_places=2) weight=models.IntegerField(default=0) cat = models.ForeignKey(to="Category", to_field="cat_id", related_name="Product", db_constraint=False, on_delete=models.CASCADE) intor = models.TextField(max_length=250)#详细介绍 brief = models.TextField(max_length=250)#商品简介 image=models.OneToOneField(to='Images',to_field='image_id',on_delete=models.CASCADE,db_constraint=False) stock = models.OneToOneField(to="Stock", to_field="stock_id", db_constraint=False, on_delete=models.CASCADE) buy_count=models.IntegerField(default=0)#购买量 disabled = models.BooleanField(default=1)#是否显示 w_order=models.IntegerField(default=0)#权重 creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Order(models.Model): order_id = models.CharField(max_length=50, unique=True, primary_key=True) status_choices = (("active", '活动订单'), ("dead", '作废订单'), ("finish", '已完成订单')) status = models.CharField(choices=status_choices, default="active", max_length=50) pay_status_choices = ((0, '未付款'), (1, '已付款')) pay_status = models.SmallIntegerField(choices=pay_status_choices, default=0) payed = models.DecimalField(max_digits=10, decimal_places=2,default=0) order_total = models.DecimalField(max_digits=10, decimal_places=2,default=0) ship_status_choices = ((0, '未发货'), (1, '已发货')) pay_app = models.CharField(max_length=100) wxuser = models.ForeignKey(to="Wxuser", to_field="id", related_name="Order", db_constraint=False,on_delete=models.CASCADE) quantity = models.IntegerField(default=0) memo = models.CharField(max_length=200, default=0) consignee_name = models.CharField(max_length=200, default=0) consignee_area = models.CharField(max_length=200, default=0) consignee_address = models.CharField(max_length=200, default=0) consignee_zip = models.CharField(max_length=200, default=0) consignee_mobile = models.CharField(max_length=200,default=0) creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.order_id class Order_items(models.Model): item_id = models.AutoField(primary_key=True) order= models.ForeignKey(to="Order", to_field="order_id", related_name="Order_items", db_constraint=False,on_delete=models.CASCADE) product=models.ForeignKey(to="Product", to_field="product_id", related_name="Order_items", db_constraint=False,on_delete=models.CASCADE,null=True) name = models.CharField(max_length=200) image = models.ForeignKey(to='Images', to_field='image_id',related_name="Order_items", on_delete=models.CASCADE,db_constraint=False) price = models.DecimalField(max_digits=10, decimal_places=2,default=0) amount=models.DecimalField(max_digits=10, decimal_places=2,default=0) nums=models.IntegerField() send_nums=models.IntegerField(null=True) brief=models.CharField(max_length=200) creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Stock(models.Model): stock_id=models.AutoField(primary_key=True) name=models.CharField(max_length=100) quantity=models.IntegerField(default=0)#库存量 creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Banner(models.Model): product = models.OneToOneField(to="Product", to_field="product_id", db_constraint=False, on_delete=models.CASCADE) w_order = models.IntegerField(default=0) # 权重 image = models.OneToOneField(to='Images', to_field='image_id', on_delete=models.CASCADE, db_constraint=False) is_show =models.BooleanField(default=1) creat_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.product.name
pro_celery
import celery import time # broker='redis://127.0.0.1:6379/2' 不加密码 backend='redis://127.0.0.1:6379/1' broker='redis://127.0.0.1:6379/2' cel=celery.Celery('test',backend=backend,broker=broker) import os, sys import django BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # 定位到你的django根目录 # sys.path.append(os.path.join(BASE_DIR, "app01")) sys.path.append(os.path.abspath(BASE_DIR)) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wxshop.settings") django.setup() from django.db import transaction @cel.task @transaction.atomic def del_order(order_id): ''' 1 拿订单查询,订单号,是否支付,活跃 2 判断data是否有 :param order_id: :return: ''' from app01 import models data=models.Order.objects.filter(order_id=order_id,pay_status=0,status="active").first() if data: item_data=models.Order_items.objects.filter(order_id=order_id).values("product","nums") # [{product:1,nums:3}] # {1:3,2:1} all_product_dict = { k['product']:k['nums'] for k in item_data} all_product_id =list(all_product_dict.keys()) products_all=models.Product.objects.filter(product_id__in=all_product_id) sid=transaction.savepoint() for product in products_all: for i in range(3): stock=product.stock.quantity new_stock=stock+all_product_dict[product.product_id] new_buy_count=product.buy_count-all_product_dict[product.product_id] res=models.Stock.objects.filter(quantity=stock,stock_id=product.stock).update(quantity=new_stock) if not res: if i==2: from app01.comment import func transaction.savepoint_rollback(sid) func.add_task(order_id,1) return else: continue else: break models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count) row=models.Order.objects.filter(order_id=order_id,pay_status=0).update(status="dead") if row: transaction.savepoint_commit(sid) else: transaction.savepoint_rollback(sid)
wxshopapi2
""" Django settings for wxshopapi2 project. Generated by 'django-admin startproject' using Django 2.0.7. For more information on this file, see https://docs.djangoproject.com/en/2.0/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/2.0/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/2.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '$v^um*l969ywfw2$3=rv5y&ehv$b@e#w&ha(%t!_+rv3=3#74n' # 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', 'app01.apps.App01Config', 'rest_framework', 'xadmin', 'crispy_forms', 'reversion', ] 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 = 'wxshopapi2.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 = 'wxshopapi2.wsgi.application' # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'wxshop', 'USER':'root', 'PASSWORD':'123456', 'HOST':'127.0.0.1', 'PORT': 3306, 'OPTIONS': {'charset': 'utf8mb4'}, } } # Password validation # https://docs.djangoproject.com/en/2.0/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/2.0/topics/i18n/ LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static'), ] MEDIA_ROOT=os.path.join(BASE_DIR,'static/media') MEDIA_URL = '/static/media/' CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379', "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", }, }, }
"""wxshop URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.0/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path import xadmin xadmin.autodiscover() # version模块自动注册需要版本控制的 Model from xadmin.plugins import xversion xversion.register_models() from django.conf.urls import url from app01.views import User,Banner,Goods,Category,Order urlpatterns = [ path(r'xadmin/', xadmin.site.urls), path('admin/', admin.site.urls), path("user/wxapp/login",User.Login.as_view()), path("banner/list",Banner.List.as_view()), path("hotgoods/list",Goods.HotGoods.as_view()), path("category/all",Category.All.as_view()), path("goods/list",Goods.List.as_view()), path("goods/detail",Goods.Detail.as_view()), path("order/create",Order.Creat.as_view()), ]