@@ -31,10 +31,10 @@ def member(request): |
||
| 31 | 31 |
rights = RightInfo.objects.filter(status=True).order_by('position')
|
| 32 | 32 |
rights = [right.data for right in rights] |
| 33 | 33 |
|
| 34 |
- goods = GoodsInfo.objects.filter(only_for_member=False, status=True).order_by('position')
|
|
| 34 |
+ goods = GoodsInfo.objects.filter(only_for_member=False, left_num__gt=0, status=True).order_by('position')
|
|
| 35 | 35 |
goods = [good.data(user_id) for good in goods][:2] |
| 36 | 36 |
|
| 37 |
- member_goods = GoodsInfo.objects.filter(only_for_member=True, minlevel__lte=user.level, status=True).order_by('position')
|
|
| 37 |
+ member_goods = GoodsInfo.objects.filter(only_for_member=True, left_num__gt=0, minlevel__lte=user.level, status=True).order_by('position')
|
|
| 38 | 38 |
member_goods = [good.data(user_id) for good in member_goods] |
| 39 | 39 |
member_goods = [good for good in member_goods if not good['has_member_exchange']] |
| 40 | 40 |
|
@@ -106,7 +106,7 @@ def goods(request): |
||
| 106 | 106 |
except UserInfo.DoesNotExist: |
| 107 | 107 |
return response(UserStatusCode.USER_NOT_FOUND) |
| 108 | 108 |
|
| 109 |
- raw_goods = GoodsInfo.objects.filter(only_for_member=False, status=True).order_by('position')
|
|
| 109 |
+ raw_goods = GoodsInfo.objects.filter(only_for_member=False, left_num__gt=0, status=True).order_by('position')
|
|
| 110 | 110 |
banners = goods = [] |
| 111 | 111 |
for good in raw_goods: |
| 112 | 112 |
if good.is_slider: |
@@ -173,7 +173,7 @@ def good_exchange(request): |
||
| 173 | 173 |
return response(UserStatusCode.USER_NOT_FOUND) |
| 174 | 174 |
|
| 175 | 175 |
try: |
| 176 |
- good = GoodsInfo.objects.get(good_id=good_id) |
|
| 176 |
+ good = GoodsInfo.objects.select_for_update().get(good_id=good_id) |
|
| 177 | 177 |
except GoodsInfo.DoesNotExist: |
| 178 | 178 |
return response(MemberGoodStatusCode.GOOD_NOT_FOUND) |
| 179 | 179 |
|
@@ -186,6 +186,9 @@ def good_exchange(request): |
||
| 186 | 186 |
user.integral -= good.integral |
| 187 | 187 |
user.save() |
| 188 | 188 |
|
| 189 |
+ good.left_num -= 1 |
|
| 190 |
+ good.save() |
|
| 191 |
+ |
|
| 189 | 192 |
GoodsOrderInfo.objects.create( |
| 190 | 193 |
user_id=user_id, |
| 191 | 194 |
good_id=good_id, |
@@ -0,0 +1,25 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+# Generated by Django 1.11.26 on 2019-12-21 12:58 |
|
| 3 |
+from __future__ import unicode_literals |
|
| 4 |
+ |
|
| 5 |
+from django.db import migrations, models |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+class Migration(migrations.Migration): |
|
| 9 |
+ |
|
| 10 |
+ dependencies = [ |
|
| 11 |
+ ('member', '0014_auto_20191221_1613'),
|
|
| 12 |
+ ] |
|
| 13 |
+ |
|
| 14 |
+ operations = [ |
|
| 15 |
+ migrations.AlterField( |
|
| 16 |
+ model_name='goodsinfo', |
|
| 17 |
+ name='left_num', |
|
| 18 |
+ field=models.IntegerField(db_index=True, default=0, help_text='\u5546\u54c1\u5e93\u5b58', verbose_name='left_num'), |
|
| 19 |
+ ), |
|
| 20 |
+ migrations.AlterField( |
|
| 21 |
+ model_name='goodsinfo', |
|
| 22 |
+ name='minlevel', |
|
| 23 |
+ field=models.IntegerField(db_index=True, default=0, help_text='\u5151\u6362\u6700\u4f4e\u4f1a\u5458\u7ea7\u522b', verbose_name='minlevel'), |
|
| 24 |
+ ), |
|
| 25 |
+ ] |
@@ -28,7 +28,7 @@ class GoodsInfo(BaseModelMixin): |
||
| 28 | 28 |
title = models.CharField(_(u'title'), max_length=255, blank=True, null=True, help_text=u'商品名称') |
| 29 | 29 |
desc = RichTextField(_(u'desc'), blank=True, null=True, help_text=u'商品描述') |
| 30 | 30 |
value = models.IntegerField(_(u'value'), default=99999, help_text=u'商品价值,单位分') |
| 31 |
- left_num = models.IntegerField(_(u'left_num'), default=0, help_text=u'商品库存') |
|
| 31 |
+ left_num = models.IntegerField(_(u'left_num'), default=0, help_text=u'商品库存', db_index=True) |
|
| 32 | 32 |
|
| 33 | 33 |
image = models.ImageField(_(u'image'), upload_to=upload_path, blank=True, null=True, help_text=u'商品图片') |
| 34 | 34 |
|
@@ -40,7 +40,7 @@ class GoodsInfo(BaseModelMixin): |
||
| 40 | 40 |
integral = models.IntegerField(_(u'integral'), default=99999, help_text=u'兑换所需积分') |
| 41 | 41 |
fee = models.IntegerField(_(u'fee'), default=99999, help_text=u'兑换需额外支付金额,单位分') |
| 42 | 42 |
|
| 43 |
- minlevel = models.IntegerField(_(u'minlevel'), default=0, help_text=u'兑换最低会员级别') |
|
| 43 |
+ minlevel = models.IntegerField(_(u'minlevel'), default=0, help_text=u'兑换最低会员级别', db_index=True) |
|
| 44 | 44 |
|
| 45 | 45 |
only_for_member = models.BooleanField(_(u'only_for_member'), default=False, help_text=u'会员专属', db_index=True) |
| 46 | 46 |
|