Django Restful Framework - 根据角色/组限制结果

时间:2016-05-18 15:52:02

标签: python django django-models django-rest-framework

我正在尝试在Django Rest Framework(Python 3.x)中构建API。作为b2b合作伙伴的要求,我们只能将其内容重新分发给特定用户。因此,我想编辑视图,仅根据系统中的用户组/角色返回某些数据。

例如,我有以下模型:

class LocalDeals(models.Model):
    deal_id = models.IntegerField(db_column='deal_ID', unique=True)  # Field name made lowercase.
    deal_url = models.CharField(db_column='deal_URL', max_length=600)  # Field name made lowercase.
    store_id = models.IntegerField(db_column='store_ID', blank=True, null=True)  # Field name made lowercase.
    store_online_id = models.IntegerField(db_column='storeOnline_ID', blank=True, null=True)  # Field name made lowercase.
    store_chain_id = models.IntegerField(db_column='storeChain_ID', blank=True, null=True)  # Field name made lowercase.
    deal_price = models.FloatField(db_column='dealPrice', blank=True, null=True)  # Field name made lowercase.
    deal_original_price = models.FloatField(db_column='dealOriginalPrice', blank=True, null=True)  # Field name made lowercase.
    deal_title = models.CharField(db_column='dealTitle', max_length=256)  # Field name made lowercase.
    store_name = models.CharField(db_column='storeName', max_length=64, blank=True, null=True)  # Field name made lowercase.
    image_small = models.CharField(db_column='smallImage', max_length=128, blank=True, null=True)  # Field name made lowercase.
    image_large = models.CharField(db_column='largeImage', max_length=128, blank=True, null=True)  # Field name made lowercase.
    store_url = models.CharField(db_column='storeURL', max_length=128, blank=True, null=True)  # Field name made lowercase.
    provider_name = models.CharField(db_column='providerName', max_length=64, blank=True, null=True)  # Field name made lowercase.
    provider_logo = models.CharField(db_column='providerLogo', max_length=128, blank=True, null=True)  # Field name made lowercase.
    user_provider_id = models.IntegerField(db_column='userProvider_ID', blank=True, null=True)  # Field name made lowercase.
    expiration_date = models.DateTimeField(db_column='expirationDate', blank=True, null=True)  # Field name made lowercase.
    create_date = models.DateTimeField(db_column='createDate', blank=True, null=True)  # Field name made lowercase.
    update_date = models.DateTimeField(db_column='updateDate')  # Field name made lowercase.
    yelp_rating = models.FloatField(db_column='yelp_rating',blank=True, null=True)
    yelp_review_count = models.IntegerField(db_column='yelp_review_count',blank=True, null=True)
    yelp_rating_img_url = models.CharField(db_column='yelp_rating_img_url',max_length=128, blank=True, null=True)
    yelp_url = models.CharField(db_column='yelp_url',max_length=128, blank=True, null=True)
    address1 = models.CharField(db_column='address1',max_length=64, blank=True, null=True)
    city = models.CharField(db_column='city',max_length=64, blank=True, null=True)
    state = models.CharField(db_column='state',max_length=32, blank=True, null=True)
    zip = models.CharField(db_column='zip',max_length=10, blank=True, null=True)
    country = models.CharField(db_column='country',max_length=32, blank=True, null=True)
    latitude = models.FloatField(db_column='latitude',blank=True, null=True)
    longitude = models.FloatField(db_column='longitude',blank=True, null=True)
    deal_code = models.CharField(db_column='dealCode', max_length=32, blank=True, null=True)  # Field name made lowercase.
    event_date = models.DateTimeField(db_column='eventDate', blank=True, null=True)  # Field name made lowercase.
    is_now_deal = models.IntegerField(db_column='isNowDeal', blank=True, null=True)  # Field name made lowercase.
    business_type = models.IntegerField(db_column='businessType', blank=True, null=True)  # Field name made lowercase.
    scoring_base = models.FloatField(db_column='scoringBase', blank=True, null=True)  # Field name made lowercase.
    deal_type = models.CharField(db_column='dealType', max_length=16, blank=True, null=True)  # Field name made lowercase.
    deal_disclaimer = models.TextField(db_column='dealDisclaimer', blank=True, null=True)  # Field name made lowercase.
    submit_id = models.IntegerField(db_column='submit_ID', blank=True, null=True)  # Field name made lowercase.
    deal_date_time = models.DateField(db_column='deal_datetime',blank=True, null=True)
    business_type_sub = models.IntegerField(db_column='businessTypeSub', blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'local_deals'
        app_label = 'api'

以下视图和序列化程序调用:

class LocalDealsViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows local_deals to be viewed.
    """
    throttle_classes = (UserRateThrottle,)
    queryset = LocalDeals.objects.all()
    serializer_class = LocalDealsSerializer

class LocalDealsSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = LocalDeals
        fields = ('deal_id','deal_url','deal_price','deal_original_price','deal_title',
                  'store_name','image_small','image_large','store_url','provider_name',
                  'expiration_date','create_date','update_date','address1','city','state',
                  'zip','country','latitude','longitude','deal_code',
                  'business_type','business_type_sub','deal_type','deal_date_time',)

如果用户不在auth_group'admin'(身份1)中,那么我想限制结果,以便显示除user_provider_id in [1,3]以外的所有结果。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

您应覆盖基于get_queryset()身份验证组的admin方法以限制结果

class LocalDealsViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows local_deals to be viewed.
    """
    throttle_classes = (UserRateThrottle,)
    serializer_class = LocalDealsSerializer

    def get_queryset(self):
        # check here if 'list' request and user not in admin auth group
        if self.action == 'list' and self.request.user not in admin auth_group: 
            # exclude results with 'user_provider_id' in [1,3]
            return LocalDeals.objects.all().exclude(user_provider_id__in=[1,3]) 

        # Otherwise return all results
        return LocalDeals.objects.all()