예제 #1
0
class RolesSerializerMixin(serializers.Serializer):
    system_roles = serializers.ManyRelatedField(
        child_relation=serializers.PrimaryKeyRelatedField(
            queryset=Role.system_roles),
        label=_('System roles'),
    )
    org_roles = serializers.ManyRelatedField(
        required=False,
        child_relation=serializers.PrimaryKeyRelatedField(
            queryset=Role.org_roles),
        label=_('Org roles'),
    )
    system_roles_display = serializers.SerializerMethodField(
        label=_('System roles'))
    org_roles_display = serializers.SerializerMethodField(label=_('Org roles'))

    @staticmethod
    def get_system_roles_display(user):
        return user.system_roles.display

    @staticmethod
    def get_org_roles_display(user):
        return user.org_roles.display

    def pop_roles_if_need(self, fields):
        request = self.context.get('request')
        view = self.context.get('view')

        if not all([request, view, hasattr(view, 'action')]):
            return fields
        if request.user.is_anonymous:
            return fields

        action = view.action or 'list'
        if action in ('partial_bulk_update', 'bulk_update', 'partial_update',
                      'update'):
            action = 'create'
        model_cls_field_mapper = {
            SystemRoleBinding: ['system_roles', 'system_roles_display'],
            OrgRoleBinding: ['org_roles', 'system_roles_display']
        }

        for model_cls, fields_names in model_cls_field_mapper.items():
            perms = RBACPermission.parse_action_model_perms(action, model_cls)
            if request.user.has_perms(perms):
                continue
            # 没有权限就去掉
            for field_name in fields_names:
                fields.pop(field_name, None)
        return fields

    def get_fields(self):
        fields = super().get_fields()
        self.pop_roles_if_need(fields)
        return fields
예제 #2
0
class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task

    class InnerTestSerializer(serializers.ModelSerializer):
        class Meta:
            model = Test
            fields = ('id', 'name', 'owner', 'repository_url', 'detail_url',
                      'external_links')

        repository_url = serializers.CharField(source='get_reposituory_url')
        detail_url = serializers.CharField(source='get_detail_url')
        # external_links = serializers.StringRelatedField(source='get_external_links')

    class InnerRecipeSerializer(RecipeSerializer):
        class Meta:
            model = Recipe
            exclude = ('tasks', )

    test = InnerTestSerializer()
    # result = ResultField()
    # status = StatusField()
    # statusbyuser = StatusByUserField()
    recipe = InnerRecipeSerializer()
    comments = serializers.ManyRelatedField(child_relation=CommentSerializer())
    logfiles = serializers.StringRelatedField(many=True)
예제 #3
0
class CommentReadModelSerializer(serializers.ModelSerializer):
    results = serializers.ManyRelatedField(
        child_relation=CommentModelSerializer(), source='ordergoods_set')

    class Meta:
        model = GoodsSKU
        fields = ['results']
예제 #4
0
class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'

    class InnerTestSerializer(serializers.ModelSerializer):
        class Meta:
            model = Test
            fields = ('id', 'name', 'owner', 'repository_url', 'detail_url',
                      'external_links', "get_absolute_url")

        repository_url = serializers.CharField(source='get_reposituory_url')
        detail_url = serializers.CharField(source='get_detail_url')
        # external_links = serializers.StringRelatedField(source='get_external_links')

    class InnerRecipeSerializer(RecipeSerializer):
        class Meta:
            model = Recipe
            # fields = "__all__"
            fields = ("id", "uid", "job", "arch", "comments")
            # from rest framework 3.3 is not possible set exclude = ('tasks', )
            # exclude = ('tasks', )

    test = InnerTestSerializer()
    # result = ResultField()
    # status = StatusField()
    # statusbyuser = StatusByUserField()
    recipe = InnerRecipeSerializer()
    comments = serializers.ManyRelatedField(child_relation=CommentSerializer())
    logfiles = serializers.StringRelatedField(many=True)
예제 #5
0
class ShortIncidentSerializer(serializers.ModelSerializer):
    id = serializers.ManyRelatedField(child_relation=incident_id)
    depth = 3

    class Meta:
        model = Incident
        fields = ('id', 'pos_lon', 'pos_lan', 'created_at')
예제 #6
0
class QuestionSerializer(serializers.Serializer):
    """
    Default Question serializer with all available fields
    """
    id = serializers.IntegerField()
    question_title = serializers.CharField(required=True, allow_blank=False,
                                           max_length=100)
    author = serializers.CharField(required=True, allow_blank=False,
                                   max_length=100)
    pub_date = serializers.DateTimeField(format="%x %X")
    question_tags = serializers.ManyRelatedField(child_relation=serializers.CharField())

    question_text = serializers.CharField(required=True, allow_blank=False,
                                          max_length=2000)

    number_of_answers = serializers.SerializerMethodField()
    rating = serializers.IntegerField()

    def create(self, validated_data):
        """
        No change with api available
        """
        pass

    def update(self, instance, validated_data):
        """
        No change with api available
        """
        pass

    def get_number_of_answers(self, obj):
        """
        :return: number of answers for number_of_answer field
        """
        return obj.answer_set.count()
예제 #7
0
class UserUpdateSerializer(serializers.Serializer):
    account = serializers.CharField(required=False)
    username = serializers.CharField(required=False)
    mobile = serializers.CharField(required=False)
    status = serializers.IntegerField(required=False)
    bran = serializers.PrimaryKeyRelatedField(
        label='所属分部',
        help_text='所属分部',
        queryset=BranchesInfo.objects.all(),
        required=False)
    roles = serializers.ManyRelatedField(
        child_relation=serializers.PrimaryKeyRelatedField(
            label='所属角色',
            help_text='用户关联的角色',
            queryset=RolesInfo.objects.all()),
        help_text='用户关联的角色',
        required=False,
        label='所属角色')

    def update(self, instance, validated_data):
        roles = validated_data.pop('roles')
        request_user = self.context.get('request').user
        if isinstance(request_user, AnonymousUser):
            request_user = None
        validated_data['modifier'] = request_user

        with transaction.atomic():
            for attr in validated_data.keys():
                setattr(instance, attr, validated_data.get(attr))
            instance.roles.set(roles)
            instance.save()
        return instance
예제 #8
0
class CategoryAuthUserSerializer(serializers.ModelSerializer):
    """Категории авторизованного пользователя"""
    links = serializers.ManyRelatedField(child_relation=LinkSetSerializer(), source='link_set')

    class Meta:
        model = Category
        fields = ['id', 'name', 'links']
예제 #9
0
class UsersSerializerAnti(serializers.ModelSerializer):
    """用户序列反化器"""

    roles = serializers.ManyRelatedField(
        child_relation=serializers.PrimaryKeyRelatedField(
            label='所属角色',
            help_text='用户关联的角色',
            queryset=RolesInfo.objects.all()),
        help_text='用户关联的角色',
        required=False,
        label='所属角色')
    creator = serializers.StringRelatedField(read_only=True)
    modifier = serializers.SlugRelatedField(read_only=True,
                                            slug_field='username')
    date_joined = serializers.DateTimeField(read_only=True,
                                            required=False,
                                            format='%Y-%m-%d %H:%M:%S')
    modify_time = serializers.DateTimeField(read_only=True,
                                            required=False,
                                            format='%Y-%m-%d %H:%M:%S')

    class Meta:
        model = UsersInfo
        fields = [
            'id',
            'account',
            'username',
            'password',
            'mobile',
            'status',
            'bran',
            'roles',
            'creator',
            'modifier',
            'date_joined',
            'modify_time',
        ]
        extra_kwargs = {
            'id': {
                'read_only': True
            },
            'password': {
                'write_only': True
            },
        }

    def create(self, validated_data):
        roles = validated_data.pop('roles')
        request_user = self.context.get('request').user
        if isinstance(request_user, AnonymousUser):
            request_user = None
        validated_data['creator'] = request_user
        validated_data['modifier'] = validated_data.get('creator')

        with transaction.atomic():
            user = UsersInfo.objects.create_user(**validated_data)
            user.roles.set(roles)
            user.save()
        return user
예제 #10
0
class OrderInfoReadModelSerializer(serializers.ModelSerializer):
    # 查询该订单的所有的商品
    goods = serializers.ManyRelatedField(OrderGoodsModelSerializer(),
                                         source='ordergoods_set')

    class Meta:
        model = models.OrderInfo
        fields = '__all__'
예제 #11
0
class CategorySerializer(serializers.ModelSerializer):
    """Список всех категорий"""
    owner = UserProjectSerializer()
    links = serializers.ManyRelatedField(child_relation=LinkSetSerializer(), source='link_set')

    class Meta:
        model = Category
        fields = ['id', 'name', 'owner', 'links']
예제 #12
0
class SentSerializer(serializers.ModelSerializer):
    TO = serializers.ManyRelatedField(UserEmailSerializer(),
                                      source='email.to_users')
    title = serializers.CharField(source='email.title')
    text = serializers.CharField(source='email.text')

    class Meta:
        model = Sent
        fields = ('TO', 'title', 'text', 'is_new')
예제 #13
0
class BaseGroupSerializer(serializers.ModelSerializer):
    permissions_list = BasePermissionSeializer(many=True,
                                               read_only=True,
                                               source='permissions')
    permissions = serializers.ManyRelatedField(
        child_relation=serializers.PrimaryKeyRelatedField(
            queryset=Permission.objects.all(), many=True, allow_null=True),
        allow_null=True)

    class Meta:
        model = Group
        fields = ('__all__')
예제 #14
0
class QuestionSerializer(serializers.Serializer):
    """
    Question serializer with all fields
    """
    id = serializers.IntegerField()
    title = serializers.CharField(required=True, allow_blank=False,
                                  max_length=100)
    author = serializers.CharField(required=True, allow_blank=False,
                                   max_length=100)
    pub_date = serializers.DateTimeField(format="%x %X")
    tags = serializers.ManyRelatedField(child_relation=serializers.CharField())

    text = serializers.CharField(required=True, allow_blank=False,
                                 max_length=2000)

    number_of_answers = serializers.SerializerMethodField()
    rank = serializers.IntegerField()

    def get_number_of_answers(self, obj):
        """
        :return: number of answers for number_of_answer field
        """
        return obj.answer_set.count()
예제 #15
0
class EmailSerializer(serializers.ModelSerializer):
    FROM = UserEmailSerializer(read_only=True, source='from_user')
    TO = serializers.ManyRelatedField(UserEmailSerializer(), source='to_users')

    class Meta:
        model = Email
        fields = ('FROM', 'TO', 'title', 'text')

    def validate_TO(self, value):
        request = self.context['request']
        users = []
        for email in set(value):
            try:
                users.append(User.objects.get(email=email))
            except User.DoesNotExist:
                messages.error(request,
                               f'Email address "{email}" does not exist')
        if users:
            emails_string = '", "'.join((u.email for u in users))
            message = f'Email sent to: "{emails_string}"'
            messages.success(request, message)
            return users

        raise ValidationError('Check the email addresses into the "TO" field')
예제 #16
0
        class BookmarkSerializer(serializers.ModelSerializer):
            tags = serializers.ManyRelatedField(source='tags')

            class Meta:
                model = Bookmark
                exclude = ('id', )
예제 #17
0
class UserSerializer(BaseModelSerializer):
    username = EmailField(max_length=75, allow_blank=False)
    first_name = serializers.CharField(max_length=30, allow_blank=True)
    last_name = serializers.CharField(max_length=30, allow_blank=True)
    email = EmailField(max_length=75, allow_blank=False)
    is_active = serializers.BooleanField(required=True)
    trading_desk = serializers.CharField(required=True, allow_blank=False)
    is_manage_user = serializers.BooleanField(read_only=True)
    date_joined = DateTimeField(read_only=True)
    user_in_groups = ListField(required=True)
    groups = serializers.ManyRelatedField(
        required=False,
        child_relation=serializers.PrimaryKeyRelatedField(
            queryset=Group.objects.all()))
    reset_password_url = serializers.CharField(required=True)

    required_in_schema = ['first_name', 'last_name', 'groups']

    # pylint: disable=old-style-class
    class Meta:
        model = User
        fields = ('user_id', 'username', 'first_name', 'last_name',
                  'full_name', 'email', 'is_active', 'user_in_groups',
                  'groups', 'trading_desk', 'trading_desk_id',
                  'is_manage_user', 'date_joined', 'reset_password_url')

    def to_representation(self, instance, **kwargs):
        to_representation_dict = super(UserSerializer, self).to_representation(
            instance, **kwargs)

        user_in_groups = []
        if 'user_in_groups' in to_representation_dict:
            for group in to_representation_dict['user_in_groups']:
                if group in TD_GROUPS or group in MANAGE_GROUPS:
                    user_in_groups.append(group)
        to_representation_dict['user_in_groups'] = user_in_groups

        if 'groups' in to_representation_dict:
            del to_representation_dict['groups']

        if 'reset_password_url' in to_representation_dict:
            del to_representation_dict['reset_password_url']

        return to_representation_dict

    @transaction.atomic()
    def create(self, request):
        reset_password_url = request.pop('reset_password_url', None)
        if reset_password_url is None:
            raise serializers.ValidationError(
                {'reset_password_url': 'This field is required'})

        if reset_password_url.find('{token}') == -1 or reset_password_url.find(
                '{username}') == -1:
            raise serializers.ValidationError({
                'reset_password_url':
                'This field must contain {token} and {username} placeholders'
            })

        groups = list(
            Group.objects.filter(
                pk__in=[int(x.pk) for x in request.pop('groups', None)]))
        if groups:
            AuditLogger.skip_next_write = True
            user = super(UserSerializer, self).create(request)
            user.date_joined = datetime.now(tzutc())
            user.groups.add(*groups)
        else:
            raise serializers.ValidationError(
                {'groups': 'User should belong to group'})

        UserProfile.objects.create(user=user)
        obj = TradingDesk.objects.filter(
            trading_desk=self.initial_data.get('trading_desk', None))
        if obj.exists():
            user.profile.trading_desk.add(obj.first())
        else:
            user.save()  # save auditlog
            raise serializers.ValidationError(
                {'trading_desk': 'User should belong to trading desk'})

        user.save()  # save auditlog

        reset_password_url = re.sub(r'\{token\}',
                                    user.get_reset_password_hash(),
                                    reset_password_url)
        reset_password_url = re.sub(r'\{username}', user.username,
                                    reset_password_url)

        attrs = {'user': user, 'reset_password_url': reset_password_url}

        send_mail(mail_to=user.username,
                  template="new_user",
                  attrs=attrs,
                  mail_from="%s <*****@*****.**>" %
                  user.trading_desk)

        return user

    @transaction.atomic()
    def update(self, instance, validated_data):
        data = deepcopy(validated_data)
        groups = data.pop('groups', [])

        AuditLogger.skip_next_write = True
        super(UserSerializer, self).update(instance, data)

        new_user_in_groups = [x.name for x in groups]
        old_user_in_groups = [x.name for x in instance.groups.all()]

        new_groups = list(
            Group.objects.filter(name__in=[
                x for x in
                [x for x in new_user_in_groups if x not in old_user_in_groups]
            ]))
        old_groups = list(
            Group.objects.filter(name__in=[
                x for x in
                [x for x in old_user_in_groups if x not in new_user_in_groups]
            ]))

        if old_groups:
            [
                x.user_set.remove(instance) for x in old_groups
                if x.name in MANAGE_GROUPS or x.name in TD_GROUPS
            ]

        if new_groups:
            instance.groups.add(*new_groups)

        instance.save()  # save auditlog
        return instance

    def is_valid(self, *args, **kwargs):
        valid = super(UserSerializer, self).is_valid(*args, **kwargs)
        instance = self.instance

        # username
        username = self.validated_data.get('username')
        if re.match(r'[^a-zA-Z0-9_\@\+\.\-]', username):
            raise serializers.ValidationError({
                'username':
                '******'
            })

        user = REGISTRY['user']
        user_groups = [g.name for g in user.groups.all()]
        user_in_groups = []
        groups = self.validated_data.get('groups', None)
        if groups:
            user_in_groups = list([
                x.name for x in Group.objects.filter(
                    pk__in=[int(x.pk) for x in groups])
            ])

        if instance:
            instance_groups = [g.name for g in instance.groups.all()]
            instance_monarch_groups = [
                g for g in instance_groups
                if str(g) in MANAGE_GROUPS + TD_GROUPS
            ]

            errors = {}
            for field in ['first_name', 'last_name']:
                if not self.validated_data.get(field, None) and getattr(
                        self.instance, field):
                    errors[field] = 'This field is required'

            if instance_monarch_groups and not self.validated_data.get(
                    'groups', None):
                errors['user_in_groups'] = 'This field is required'

            if errors:
                raise serializers.ValidationError(errors)

        if TD_ACCOUNT_MANAGER_GROUP in user_groups:
            for group in user_in_groups:
                if group not in TD_GROUPS:
                    raise serializers.ValidationError('Available groups:%s' %
                                                      TD_GROUPS.join(','))

        obj = TradingDesk.objects.filter(
            trading_desk=self.initial_data.get('trading_desk', None))
        if obj.exists():
            obj = obj.first()
        else:
            raise serializers.ValidationError(
                {'trading_desk': 'Invalid value'})

        group_list = TD_GROUPS[:]
        if obj.pk == MANAGE_TRADING_DESK_ID:
            group_list += MANAGE_GROUPS

        for group in user_in_groups:
            if group not in group_list:
                raise serializers.ValidationError('Available groups:%s' %
                                                  ','.join(group_list))

        return valid
예제 #18
0
class OrderSerializerAnti(serializers.ModelSerializer):
    """订单序反列化器"""

    goods = GoodSerializer(many=True)
    operators = serializers.ManyRelatedField(
        child_relation=serializers.PrimaryKeyRelatedField(
            label='所属角色',
            help_text='订单关联的操作员',
            queryset=UsersInfo.objects.all()),
        help_text='用户关联的角色',
        required=False,
        label='所属角色')

    class Meta:
        model = OrdersInfo
        fields = [
            'id',
            'trans_code',
            'order_status',
            'freight',
            'customer',
            'channel',
            'good_type',
            'pay_type',
            'operators',
            'collection_money',
            'v_w_rate',
            'volume',
            'volume_w',
            'weight',
            'price_w',
            'number',
            'transport_site',
            'goods_name',
            'goods_name_en',
            'flight_number',
            'remark_comment',
            'order_time',
            'receiver',
            'goods',
        ]
        extra_kwargs = {
            'id': {
                'help_text': '订单号',
                'read_only': True
            },
        }

    def create(self, validated_data):
        request_user = self.initial_data.get('request_user')
        if isinstance(request_user, AnonymousUser):
            request_user = None
        validated_data['creator'] = request_user
        validated_data['modifier'] = validated_data.get('creator')

        goods = validated_data.pop('goods')
        operators = validated_data.pop('operators')
        with transaction.atomic():
            order = OrdersInfo.objects.create(**validated_data)
            order.operators.set(operators)
            for good in goods:
                good['order_id'] = order.id
                good['request_user'] = request_user
            serializer = GoodSerializer(data=goods, many=True)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            order.goods.set(serializer.instance)
            order.save()
        return order

    def update(self, instance, validated_data):
        with transaction.atomic():
            request_user = self.initial_data.get('request_user')
            if isinstance(request_user, AnonymousUser):
                request_user = None
            validated_data['modifier'] = request_user

            GoodsInfo.objects.filter(order=instance).delete()
            Order2Operator.objects.filter(order=instance).delete()
            goods = validated_data.pop('goods')
            operators = validated_data.pop('operators')

            with transaction.atomic():
                OrdersInfo.objects.filter(id=instance.id).update(
                    **validated_data)
                order = OrdersInfo.objects.get(id=instance.id)
                order.operators.set(operators)
                for good in goods:
                    good['order_id'] = order.id
                    good['request_user'] = request_user
                serializer = GoodSerializer(data=goods, many=True)
                serializer.is_valid(raise_exception=True)
                serializer.save()
                order.goods.set(serializer.instance)
                order.save()
            return order
예제 #19
0
        class ReadOnlyManyToManySerializer(serializers.ModelSerializer):
            rel = serializers.ManyRelatedField(read_only=True)

            class Meta:
                model = ReadOnlyManyToManyModel
예제 #20
0
class CampaignSerializer(serializers.ModelSerializer):
    ctr = serializers.FloatField(read_only=True)
    segments = serializers.ManyRelatedField(
        child_relation=serializers.PrimaryKeyRelatedField(
            queryset=Segment.objects.all()),
        allow_empty=True,
        required=False,
        write_only=True)

    def __totimestamp_posix(self, dt, epoch=datetime(1970, 1, 1)):
        utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
        return (utc_naive - epoch).total_seconds()

    def __update_website_and_segments_relations(self, requesting_user):
        # ToDo Incase of acess management, we need to change this
        self.fields.get(
            'segments'
        ).child_relation = requesting_user.website.segment_set.all()

    def validate_scheduled_at_and_timezone(self, scheduled_at):
        if not scheduled_at:
            raise ValidationError(_("Scheduled time is required!"))
        # local = pytz.timezone(scheduled_at_timezone)
        # naive = scheduled_at
        # naive = naive.replace(tzinfo=None)
        # local_dt = local.localize(naive, is_dst=None)
        # scheduled_at = local_dt.astimezone(pytz.timezone(settings.TIME_ZONE))
        time_right_now = pytz.timezone(settings.TIME_ZONE).localize(
            datetime.now())
        if self.__totimestamp_posix(scheduled_at) <= self.__totimestamp_posix(
                time_right_now):
            raise ValidationError(_("Scheduled time can't be in the past!"))

    def validate(self, attrs):
        self.__update_website_and_segments_relations(
            self.context['request'].user)
        attrs = super(CampaignSerializer, self).validate(attrs)
        if not attrs.get('immediately', True):
            self.validate_scheduled_at_and_timezone(
                attrs.get('scheduled_at', None))
        return attrs

    def create(self, validated_data):
        if validated_data.get('scheduled_at') is not None:
            validated_data['status'] = CampaignStatus.SCHEDULED
        return super(CampaignSerializer, self).create(validated_data)

    class Meta:
        model = Campaign
        exclude = ('auth', )
        extra_kwargs = {
            'ctr': {
                'read_only': True
            },
            'status': {
                'read_only': True
            },
            'sender': {
                'read_only': True
            },
            'total_subs': {
                'read_only': True
            },
            'sent_subs': {
                'read_only': True
            },
            'clicks': {
                'read_only': True
            },
            'revenue': {
                'read_only': True
            },
            'impressions': {
                'read_only': True
            },
            'closed': {
                'read_only': True
            },
            'website': {
                'read_only': True
            },
        }