功能模块分为两大块,分别为简易用户及用户组管理模块以及枪杀模块。
urls设计
/ 首页
/admin 自带用户管理页面
/ctr 用户组管理
/api-auth api认证
/seckill/list 显示所有枪杀商品信息
/seckill/(?P<pk>[0-9]+)/detail 显示某个枪杀商品详细信息
/seckill/time/now 显示当前信息
/seckill/(?P<pk>[0-9]+)/url 暴露抢杀的url
/seckill/setphone 设置电话
/seckill/kill 抢杀
model层
用户管理模块的模型为框架本身所有,抢杀模块的模型包括商品信息,抢杀记录,抢杀地址暴露模型。
seckill/models.py
商品信息
class Seckill(models.Model):
seckill_id = models.BigIntegerField(primary_key=True)
name = models.CharField(max_length=120)
number = models.IntegerField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
create_time = models.DateTimeField()
def __unicode__(self):
return self.name
class Meta:
managed = True
db_table = 'seckill'.
抢杀记录
class SuccessKilled(models.Model):
id = models.BigIntegerField(primary_key=True)
seckill_id = models.BigIntegerField()
user_phone = models.BigIntegerField()
state = models.IntegerField()
create_time = models.DateTimeField()
class Meta:
managed = True
db_table = 'success_killed'
暴露url
#商品不存在时
class Exposed(models.Model):
exposed=models.BooleanField()
seckill_id=models.BigIntegerField()
#抢杀未开放时
class ExposedNoOpen(Exposed):
now = models.DateTimeField()
start = models.DateTimeField()
end = models.DateTimeField()
#可抢杀
class ExposedOpen(Exposed):
md5= models.CharField(max_length=100)
序列化
userAdmin\serializers.py
对User以及Group进行序列化
#对User进行序列化
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model=User
fields=('url','username','email','groups')
#对Group进行序列化
class GroupSerializers(serializers.HyperlinkedModelSerializer):
class Meta:
model=Group
fields=('url','name')
seckill\serializers.py
对抢杀模型进行序列化
# 抢杀商品的序列化
class SeckillSerializer(serializers.ModelSerializer):
class Meta:
model=Seckill
fields=('seckill_id','name','number','start_time','end_time','create_time')
class SuccessKilledSerializer(serializers.ModelSerializer):
class Meta:
model = SuccessKilled
fields = ('seckill_id', 'user_phone', 'state', 'create_time')
class ExposedNoIdSerializer(serializers.ModelSerializer):
class Meta:
model = Exposed
fields = ('exposed', 'seckill_id')
class ExposedNoOpenSerializer(serializers.ModelSerializer):
class Meta:
model = ExposedNoOpen
fields = ('exposed', 'seckill_id', 'now', 'start','end')
class ExposedOpenSerializer(serializers.ModelSerializer):
class Meta:
model = ExposedOpen
fields = ('exposed', 'seckill_id', 'md5')
视图的实现
用户管理的视图
#首页显示欢迎字符
def index(request):
return HttpResponse(u"欢迎进入抢杀!")
#用户信息的输出
class UserViewSet(viewsets.ModelViewSet):
"""
用户界面
"""
queryset=User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
#组的输出
class GroupViewSet(viewsets.ModelViewSet):
"""
组界面
"""
queryset=Group.objects.all()
serializer_class = GroupSerializers
抢杀的视图
#抢杀商品的显示和新建
class SeckillList(generics.ListCreateAPIView):
queryset = Seckill.objects.all()
serializer_class = SeckillSerializer
#抢杀商品的详细信息
class seckill_detail(viewsets.ViewSet):
def retrieve(self, request,pk=None):
queryset = Seckill.objects.all()
user = get_object_or_404(queryset, pk=pk)
serializer = SeckillSerializer(user)
return Response(serializer.data)
#显示当前时间
@api_view(['GET'])
def seckill_time(request):
now=datetime.datetime.fromtimestamp(time.time())
now={"now":now}
return Response(now)
#暴露url
@api_view(['GET'])
def expose_url(request,pk):
#是否存在商品信息,不存在则显示相关信息
try:
seckill = Seckill.objects.get(seckill_id=pk)
except:
return Response(ExposedNoIdSerializer(Exposed(exposed=False,seckill_id=pk)).data)
#检验是否在抢杀时间范围内,如果不在,则显示相关信息
now=datetime.datetime.fromtimestamp(time.time())
start=seckill.start_time.replace(tzinfo=None)
end=seckill.end_time.replace(tzinfo=None)
print now,start,end
if start > now or end < now:
nowStr=now.strftime('%Y-%m-%d %H:%M:%S')
staStr = start.strftime('%Y-%m-%d %H:%M:%S')
endStr = end.strftime('%Y-%m-%d %H:%M:%S')
return Response(ExposedNoOpenSerializer(ExposedNoOpen(exposed=False,seckill_id=pk,now=nowStr,start=staStr,end=endStr)).data)
md5=getMd5(pk)
print ExposedOpenSerializer(ExposedOpen(exposed=True, seckill_id=pk, md5=md5)).data
#如果在暴露时间范围内,则暴露信息,暴露失败则显示暴露失败
try:
return Response(ExposedOpenSerializer(ExposedOpen(exposed=True,seckill_id=pk,md5=md5)).data)
except:
return Response({'error':'暴露失败!'})
#其中getMd5()的函数如下:
# coding:utf-8
import hashlib
def getMd5(ac):
salt='/hferjberg'
value=str(ac)+salt
m5=hashlib.md5()
m5.update(value)
return m5.hexdigest()
#设置手机号码,保存到session中
@csrf_exempt
def set_phone(request):
if request.method == 'POST':
phone=request.POST.get('phone','')
request.session['phone']=phone
return HttpResponseRedirect('./kill')
else:
return HttpResponse("set failure.")
#显示抢杀信息及进行抢杀
@api_view(['GET','POST'])
def killone(request):
"""
:param request:
:return:
"""
#显示抢杀信息
if request.method == 'GET':
successKilled=SuccessKilled.objects.all()
serializer=SuccessKilledSerializer(successKilled,many=True)
return Response(serializer.data)
#进行抢杀
if request.method == 'POST':
print request.data
user_phone = long(request.data['user_phone'])
seckill_id = long(request.data['seckill_id'])
#判断发送的phone与session中的是否一致,不一致则返回号码不对
if user_phone!=request.session.get('phone',''):
print request.session.get('phone','')
return Response({'message':'电话号码不对'})
#判断seckill_id是否存在,不存在则显示秒杀商品不存在
if seckill_id not in [i.seckill_id for i in Seckill.objects.all()]:
print seckill_id==1000L
print [i.seckill_id for i in Seckill.objects.all()]
return Response({'message':'秒杀商品不存在'})
#获取该商品信息
seckill = Seckill.objects.get(seckill_id=seckill_id)
#判断是否在抢杀时间范围内,如果不在,则显示对应信息
if datetime.datetime.fromtimestamp( time.time())<seckill.start_time.replace(tzinfo=None):
return Response({'message':'还未开始'})
if datetime.datetime.fromtimestamp(time.time()) > seckill.end_time.replace(tzinfo=None):
return Response({'message':'已经结束'})
#判断抢杀是否重复
idstr = [str(i.seckill_id) for i in SuccessKilled.objects.all()]
phstr = [str(i.user_phone) for i in SuccessKilled.objects.all()]
if str(user_phone)+str(seckill_id) not in [phstr[i]+idstr[i] for i in range(len(phstr))]:
#对商品数减1
seckill.number=seckill.number-1
seckill.save()
#返回相应信息
obj=SuccessKilled(seckill_id=seckill_id, user_phone=user_phone,state=1,create_time=seckill.create_time)
return Response({'mesage':'抢杀成功'})
else:
return Response({'message':'重复秒杀'})