zoukankan      html  css  js  c++  java
  • 路飞项目深科技相关表结构及购物车

    # ######################## 深科技相关 ########################
    class ArticleSource(models.Model):
        """文章来源"""
        name = models.CharField(max_length=64, unique=True)
    
        class Meta:
            verbose_name_plural = "16. 文章来源"
    
        def __str__(self):
            return self.name
    
    class Article(models.Model):
        """文章资讯"""
        title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="标题")
        source = models.ForeignKey("ArticleSource", verbose_name="来源")
        article_type_choices = ((0, '资讯'), (1, '视频'))
        article_type = models.SmallIntegerField(choices=article_type_choices, default=0)
        brief = models.TextField(max_length=512, verbose_name="摘要")
        head_img = models.CharField(max_length=255)
        content = models.TextField(verbose_name="文章正文")
        pub_date = models.DateTimeField(verbose_name="上架日期")
        offline_date = models.DateTimeField(verbose_name="下架日期")
        status_choices = ((0, '在线'), (1, '下线'))
        status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="状态")
        order = models.SmallIntegerField(default=0, verbose_name="权重", help_text="文章想置顶,可以把数字调大,不要超过1000")
        vid = models.CharField(max_length=128, verbose_name="视频VID", help_text="文章类型是视频, 则需要添加视频VID", blank=True, null=True)
        comment_num = models.SmallIntegerField(default=0, verbose_name="评论数")
        agree_num = models.SmallIntegerField(default=0, verbose_name="点赞数")
        view_num = models.SmallIntegerField(default=0, verbose_name="观看数")
        collect_num = models.SmallIntegerField(default=0, verbose_name="收藏数")
    
        # tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
        date = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")
    
        position_choices = ((0, '信息流'), (1, 'banner大图'), (2, 'banner小图'))
        position = models.SmallIntegerField(choices=position_choices, default=0, verbose_name="位置")
    
    
        #comment = GenericRelation("Comment")
    
        class Meta:
            verbose_name_plural = "17. 文章"
    
        def __str__(self):
            return "%s-%s" % (self.source, self.title)
    
    class Collection(models.Model):
        """收藏"""
        content_type = models.ForeignKey(ContentType)
        object_id = models.PositiveIntegerField()
        content_object = GenericForeignKey('content_type', 'object_id')
    
        account = models.ForeignKey("Account")
        date = models.DateTimeField(auto_now_add=True)
    
        class Meta:
            unique_together = ('content_type', 'object_id', 'account')
            verbose_name_plural = "18. 通用收藏表"
    
    class Comment(models.Model):
        """通用的评论表"""
        content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="类型")
        object_id = models.PositiveIntegerField(blank=True, null=True)
        content_object = GenericForeignKey('content_type', 'object_id')
    
        p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父级评论")
        content = models.TextField(max_length=1024)
        account = models.ForeignKey("Account", verbose_name="会员名")
        disagree_number = models.IntegerField(default=0, verbose_name="踩")
        agree_number = models.IntegerField(default=0, verbose_name="赞同数")
        date = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return self.content
    
        class Meta:
            verbose_name_plural = "19. 通用评论表"
    
    class Account(models.Model):
        username = models.CharField("用户名", max_length=64, unique=True)
        password = models.CharField("密码", max_length=64)
    
    class UserAuthToken(models.Model):
        """
        用户Token表
        """
        user = models.OneToOneField(to="Account")
        token = models.CharField(max_length=64, unique=True)
    

     路飞的深科技结构?

    • -文章来源
    • -文章详细
    • -收藏
    • -点赞
    • -评论
    • -用户
    • -用户token

    路飞购物车

    加入购物车,保存到redis。

    •  因为购物车只是一个暂时的状态,当结算完成的实收会删除购物车的内容.且购物车的操作可能比较频繁,因为客户会考虑的比较多
    • 如果只用数据库的话,那么每次修改都对数据库进行修改,数据库的压力会比较大.
    • 如果用redis+数据库,比如一天放到redis里,然后12点后存放到数据库.这个方案也是可以
      •  但是如果存在数据库,那么就需要一个购物车的表结构.
      •  而reids可以不用创建表结构,就能完成同样的事情,而且性能更高
       

    路飞购物车字典是如何构造的?

        {    # luffy_shopping_car_用户id_课程id
            luffy_shopping_car_6_1:{
                            'title':'xxxxx',
                            'img':'xxx'
                            'prolicy':{
                                10:{'name':'有效期1个月','price':123},
                                11:{'name':'有效期1个月','price':123},
                                12:{'name':'有效期1个月','price':123},
                            'defalut_prolicy':10,
                            },
            },
            luffy_shopping_car_6_2:{
            ...
            },
            luffy_shopping_car_6_3:{
            ...
            }
        }
    

     settings中配置redis

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://140.143.227.206:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100},
                 "PASSWORD": "1234",
            }
        }
    }
    settings中redis的配置
    SHOPPING_CAR_KEY = "luffy_shopping_car_%s_%s"
    

     url.py

    url(r'^shoppingcar/$', shoppingcar.ShoppingCarViewSet.as_view()),
    

     认证:

    class LuffyAuth(BaseAuthentication):
    
        def authenticate(self, request):
            """
            用户请求进行认证
            :param request:
            :return:
            """
            # http://wwwww...c0ovmadfasd/?token=adfasdfasdf
            token = request.query_params.get('token')
            obj = models.UserAuthToken.objects.filter(token=token).first()
            if not obj:
                raise AuthenticationFailed({'code':1001,'error':'认证失败'})
    
            return (obj.user.username,obj)
    认证

    视图,实现增删改查

    购物车的实现思路

    1.用户选择:课程 价格策略,提交
            2.获取课程 价格策略进行合法校验(数据库)
            3.数据获取,构造结构:
                {
                    shopping_car_用户id_课程id:{
                        'title':'',
                         img:'xxx',
                         policy:{
                         },
                         default:''
                    }
                
                }
            4. 将数据以字典的形式保存到redis中.
            
        修改:
            1.用户选择:课程 价格策略,提交
            2.获取课程 价格策略进行合法校验(redis查询)
            3.更新
            
        删除:
            1.用户选择:课程 价格策略,提交
            2.获取课程 价格策略进行合法校验(redis查询)
            3.删除
            
        查看:1.构造key_shopping_car_用户ID_*
             2.scan_iter
    
    POST请求:购物车中添加一条数据
    					  请求体:
    						{
    							courseid:1,
    							policy_id:10
    						}
    		后台:
    			检验当前课程是否有此价格策略,合法:将数据构造字典,再添加到redis

    GET请求:查看自己购物车中的所有数据 获取当前登录用户ID,根据用户ID去redis的购物车中获取数据。 DELETE请求:删除购物车中的数据 请求体: { course_ids:[1,2] } PUT/PATCH请求:更新价格策略 请求体: { courseid:1, policy_id:13 }
    class ShoppingCarViewSet(APIView):
        authentication_classes = [LuffyAuth,]
        conn = get_redis_connection("default") # 类下的全局 下面用加self
    
        def post(self, request, *args, **kwargs):
            """
            将课程添加到购物车
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            ret = BaseResponse()
            try:
                # 1. 获取用户提交的课程ID和价格策略ID
                course_id = int(request.data.get('courseid'))
                policy_id = int(request.data.get('policyid'))
    
                # 2. 获取专题课信息
                course = models.Course.objects.get(id=course_id)
    
                # 3. 获取该课程相关的所有价格策略
                price_policy_list = course.price_policy.all()
                price_policy_dict = {}
                for item in price_policy_list:
                    price_policy_dict[item.id] = {
                        "period":item.valid_period,
                        "period_display":item.get_valid_period_display(),
                        "price":item.price,
                    }
    
                # 4. 判断用户提交的价格策略是否合法
                if policy_id not in price_policy_dict:
                    # 价格策略不合法
                    raise PricePolicyInvalid('价格策略不合法')
    
                # 5. 将购物信息添加到redis中
                # self.conn
                # car_key = "luffy_shopping_car_%s_%s"
                car_key = settings.SHOPPING_CAR_KEY %(request.auth.user_id,course_id,)
                car_dict = {
                    'title':course.name,
                    'img':course.course_img,
                    'default_policy':policy_id,
                    'policy':json.dumps(price_policy_dict)
                }
                # conn = get_redis_connection("default")
                self.conn.hmset(car_key,car_dict)
                ret.data = '添加成功'
    
            except PricePolicyInvalid as e:
                ret.code = 2001
                ret.error = e.msg
            except ObjectDoesNotExist as e:
                ret.code = 2001
                ret.error = '课程不存在'
            except Exception as e:
                ret.code = 1001
                ret.error = '获取购物车失败'
            return Response(ret.dict)
    
        def delete(self, request, *args, **kwargs):
            """
            购物车中删除课程
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            ret = BaseResponse()
            try:
                course_id_list = request.data.get('courseids')
                key_list = [ settings.SHOPPING_CAR_KEY %(request.auth.user_id,course_id,) for course_id in course_id_list]
                self.conn.delete(*key_list)
            except Exception as e:
                ret.code = 1002
                ret.error = "删除失败"
    
            return Response(ret.dict)
    
        def patch(self, request, *args, **kwargs):
            """
            修改课程的价格策略
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            ret = BaseResponse()
            try:
                # 1. 获取价格策略ID和课程ID
                course_id = int(request.data.get('courseid'))
                policy_id = str(request.data.get('policyid'))
    
                # 2. 拼接课程的key
                key = settings.SHOPPING_CAR_KEY %(request.auth.user_id,course_id,)
                if not self.conn.exists(key):
                    ret.code = 1002
                    ret.error = "购物车中不存在此课程"
                    return Response(ret.dict)
                # 3. redis中获取所有的价格策略
                policy_dict = json.loads(str(self.conn.hget(key,'policy'),encoding='utf-8'))
                if policy_id not in policy_dict:
                    ret.code = 1003
                    ret.error = "价格策略不合法"
                    return Response(ret.dict)
    
                # 4. 在购物车中修改该课程的默认价格策略
                self.conn.hset(key,'default_policy',policy_id)
    
                ret.data = "修改成功"
    
            except Exception as e:
                ret.code = 1004
                ret.error = "修改失败"
    
            return Response(ret.dict)
    
        def get(self,request, *args, **kwargs):
            """
            查看购物车中所有的商品
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            ret = BaseResponse()
            try:
                key_match = settings.SHOPPING_CAR_KEY %(request.auth.user_id,"*")
    
                course_list = []
    
                for key in self.conn.scan_iter(key_match,count=10):
                    info = {
                        "title":self.conn.hget(key,'title').decode('utf-8'),
                        "img":self.conn.hget(key,'img').decode('utf-8'),
                        "policy":json.loads(self.conn.hget(key,'policy').decode('utf-8')),
                        "default_policy":self.conn.hget(key,'default_policy').decode('utf-8')
                    }
                    course_list.append(info)
                ret.data = course_list
            except Exception as e:
                ret.code = 1002
                ret.error = "获取失败"
            return Response(ret.dict)
    view.py

    I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我

  • 相关阅读:
    操作文件和目录【TLCL】
    nginx location正则写法
    elasticsearch分词器ik
    mongodb权限管理
    kafka调试遇到的问题
    mysql 安装
    jenkins 安装 + maven + git部署
    FTP服务搭建
    根据终端类型返回不同的访问内容
    上传jar包至nexus
  • 原文地址:https://www.cnblogs.com/weidaijie/p/10507903.html
Copyright © 2011-2022 走看看