class RecursiveSerializer(serializers.Serializer):
    pk = serializers.CharField()
    recursive_field = PresentablePrimaryKeyRelatedField(
        queryset=MockQueryset([]),
        presentation_serializer="tests.test_relations.RecursiveSerializer",
    )
    recursive_fields = PresentablePrimaryKeyRelatedField(
        queryset=MockQueryset([]),
        presentation_serializer="tests.test_relations.RecursiveSerializer",
        many=True)
 def setUp(self):
     self.queryset = MockQueryset([
         MockObject(pk=1, name="foo"),
         MockObject(pk=2, name="bar"),
         MockObject(pk=3, name="baz"),
     ])
     self.instance = self.queryset.items[2]
     self.field = PresentablePrimaryKeyRelatedField(
         queryset=self.queryset,
         presentation_serializer=PresentationSerializer)
Пример #3
0
class TemplateDetailSerializer(serializers.ModelSerializer):
    revenue_program = PresentablePrimaryKeyRelatedField(
        queryset=RevenueProgram.objects.all(),
        presentation_serializer=RevenueProgramInlineSerializer,
        read_source=None,
        default=None,
        allow_null=True,
        required=False,
    )
    page = PresentablePrimaryKeyRelatedField(
        queryset=DonationPage.objects.all(),
        presentation_serializer=DonationPageFullDetailSerializer,
        read_source=None,
        required=False,
        allow_null=True,
    )

    def create(self, validated_data):
        page = validated_data.pop("page", None)
        if page:
            return page.make_template_from_page(validated_data)
        return super().create(validated_data)

    def validate_page(self, page):
        """Note on why"""
        if page and self.initial_data.get("revenue_program") is None:
            self.initial_data["revenue_program"] = page.revenue_program.pk
        return page

    class Meta:
        model = Template
        fields = [
            "id",
            "page",
            "name",
            "heading",
            "revenue_program",
            "graphic",
            "header_bg_image",
            "header_logo",
            "header_link",
            "styles",
            "elements",
            "sidebar_elements",
            "thank_you_redirect",
            "post_thank_you_redirect",
        ]
        validators = [
            ValidateFkReferenceOwnership(fk_attribute="page"),
            UniqueTogetherValidator(
                queryset=Template.objects.all(),
                fields=["name", "revenue_program"],
                message="Template name already in use",
            ),
        ]
class SerializerWithPresentable(serializers.Serializer):
    test_many_field = PresentablePrimaryKeyRelatedField(
        queryset=MockQueryset([]),
        presentation_serializer=PresentationSerializer,
        read_source="foo_property",
        many=True)
    test_function_field = PresentablePrimaryKeyRelatedField(
        queryset=MockQueryset([]),
        presentation_serializer=PresentationSerializer,
        read_source="foo_function",
        many=True)
    test_field = PresentablePrimaryKeyRelatedField(
        queryset=MockQueryset([MockObject(pk=1, name="foo")]),
        presentation_serializer=PresentationSerializer,
        read_source="bar_property",
        many=False)
class TestPresentablePrimaryKeyRelatedField(APISimpleTestCase):
    def setUp(self):
        self.queryset = MockQueryset([
            MockObject(pk=1, name="foo"),
            MockObject(pk=2, name="bar"),
            MockObject(pk=3, name="baz"),
        ])
        self.instance = self.queryset.items[2]
        self.field = PresentablePrimaryKeyRelatedField(
            queryset=self.queryset,
            presentation_serializer=PresentationSerializer)

    def test_representation(self):
        representation = self.field.to_representation(self.instance)
        expected_representation = PresentationSerializer(self.instance).data
        assert representation == expected_representation

    def test_read_source_with_context(self):
        representation = SerializerWithPresentable(self.instance)
        expected_representation = [
            PresentationSerializer(x).data for x in MockObject().foo_property
        ]
        assert representation.data[
            'test_many_field'] == expected_representation
        assert representation.data[
            'test_function_field'] == expected_representation

        expected_representation = PresentationSerializer(
            MockObject().bar_property).data
        assert representation.data['test_field'] == expected_representation
Пример #6
0
class RatingSerializer(serializers.ModelSerializer):

    rated_by = PresentablePrimaryKeyRelatedField(
        queryset=User.objects,
        presentation_serializer=UserSerializer
    )
    venue = PresentablePrimaryKeyRelatedField(
        queryset=Venue.objects,
        presentation_serializer=VenueSerializer
    )

    class Meta:
        model = Rating
        fields = ('id', 'rating', 'venue', 'rated_by')

    def create(self, validated_data):
        return Rating.objects.create(**validated_data)
Пример #7
0
class CommentSerializer(serializers.ModelSerializer):

    commented_by = PresentablePrimaryKeyRelatedField(
        queryset=User.objects,
        presentation_serializer=UserSerializer
    )
    commented_to = PresentablePrimaryKeyRelatedField(
        queryset=Venue.objects,
        presentation_serializer=VenueSerializer
    )

    class Meta:
        model = Comment
        fields = ('id', 'title', 'body', 'commented_by', 'commented_to', 'created_date')

    def create(self, validated_data):
        return Comment.objects.create(**validated_data)
Пример #8
0
class AppointmentRatingSerializer(AppointmentRatingBaseSerializer):
    class Meta:
        model = AppointmentRating
        fields = ('id', 'appointment', 'rate', 'comment', )

    rate = serializers.IntegerField(min_value=1, max_value=5)
    appointment = PresentablePrimaryKeyRelatedField(
        presentation_serializer=AppointmentSerializer,
        queryset=Appointment.objects.all(),
    )
Пример #9
0
class VenueSerializer(serializers.ModelSerializer):

    created_by = PresentablePrimaryKeyRelatedField(
        queryset=User.objects,
        presentation_serializer=UserSerializer
    )
    type = PresentablePrimaryKeyRelatedField(
        queryset=VenueType.objects,
        presentation_serializer=VenueTypeSerializer
    )

    class Meta:
        model = Venue
        fields = ('id', 'name', 'description', 'address', 'phone_number', 'created_by', 'type', 'average_rating',
                  'vote_count', 'comment_count')

    def create(self, validated_data):
        rating_data = validated_data.pop('rating')
        venue = Venue.objects.create(**validated_data)
        Rating.objects.create(venue=venue, **rating_data)
        return venue
Пример #10
0
class VenueTypeSerializer(serializers.ModelSerializer):

    created_by = PresentablePrimaryKeyRelatedField(
        queryset=User.objects,
        presentation_serializer=UserSerializer
    )

    class Meta:
        model = VenueType
        fields = ('id', 'venue_type', 'created_by', 'slug')

    def create(self, validated_data):
        return VenueType.objects.create(**validated_data)
Пример #11
0
class RecipeSerializer(serializers.ModelSerializer):
    images = PresentablePrimaryKeyRelatedField(
        presentation_serializer=ImageSerializer,
        queryset=Image.objects.all(),
        many=True,
        allow_empty=False)
    author = PresentablePrimaryKeyRelatedField(
        presentation_serializer=UserSerializer, read_only=True)
    ingredients = PresentablePrimaryKeyRelatedField(
        presentation_serializer=IngredientSerializer,
        queryset=Ingredient.objects.all(),
        many=True,
        allow_empty=False)
    average_rate = serializers.FloatField(read_only=True)
    like_count = serializers.IntegerField(read_only=True)
    rate_count = serializers.IntegerField(read_only=True)

    class Meta:
        model = Recipe
        fields = ('id', 'author', 'title', 'description', 'difficulty',
                  'ingredients', 'like_count', 'average_rate', 'rate_count',
                  'images')
Пример #12
0
class TestPresentablePrimaryKeyRelatedField(APISimpleTestCase):
    def setUp(self):
        self.queryset = MockQueryset([
            MockObject(pk=1, name="foo"),
            MockObject(pk=2, name="bar"),
            MockObject(pk=3, name="baz"),
        ])
        self.instance = self.queryset.items[2]
        self.field = PresentablePrimaryKeyRelatedField(
            queryset=self.queryset,
            presentation_serializer=PresentationSerializer)

    def test_representation(self):
        representation = self.field.to_representation(self.instance)
        expected_representation = PresentationSerializer(self.instance).data
        assert representation == expected_representation
Пример #13
0
class AdvertSerializerBrief(serializers.ModelSerializer):
    advert_category = serializers.SlugRelatedField(
        slug_field='name', queryset=AdvertCategory.objects.all())
    city = serializers.SlugRelatedField(slug_field='name',
                                        queryset=City.objects.all())
    advert_status = serializers.SlugRelatedField(
        slug_field='name', queryset=AdvertStatus.objects.all())
    user = PresentablePrimaryKeyRelatedField(
        queryset=User.objects.all(),
        presentation_serializer=UserSerializerBrief,
        source='creator')
    image = ThumbnailImageField(represent_in_base64=True)

    class Meta:
        model = Advert
        fields = ('id', 'advert_category', 'city', 'advert_status', 'user',
                  'title', 'price', 'image')
Пример #14
0
class StyleListSerializer(StyleInlineSerializer):

    revenue_program = PresentablePrimaryKeyRelatedField(
        queryset=RevenueProgram.objects.all(),
        presentation_serializer=RevenueProgramInlineSerializer,
        read_source=None,
    )
    used_live = serializers.SerializerMethodField()

    def get_used_live(self, obj):
        return DonationPage.objects.filter(
            styles=obj, published_date__lte=timezone.now()).exists()

    def to_internal_value(self, data):
        """
        Data comes in as a dict with name and styles flattened. We need
        to stick styles in its own value and pull out name.
        """
        name = data.pop("name", None)
        revenue_program = data.pop("revenue_program", None)
        data = {
            "name": name,
            "revenue_program": revenue_program,
            "styles": data,
        }
        return super().to_internal_value(data)

    class Meta:
        model = Style
        fields = (
            "id",
            "created",
            "modified",
            "name",
            "styles",
            "revenue_program",
            "used_live",
        )
        validators = [
            ValidateFkReferenceOwnership(fk_attribute="revenue_program"),
            UniqueTogetherValidator(queryset=Style.objects.all(),
                                    fields=["revenue_program", "name"]),
        ]
Пример #15
0
class AdvertSerializer(serializers.ModelSerializer):
    image = CustomizedBase64ImageField(represent_in_base64=True,
                                       required=False)
    advert_category = serializers.SlugRelatedField(
        slug_field='name', queryset=AdvertCategory.objects.all())
    city = serializers.SlugRelatedField(slug_field='name',
                                        queryset=City.objects.all())
    promotion = serializers.SlugRelatedField(
        slug_field='name', queryset=AdvertPromotion.objects.all())
    advert_status = serializers.SlugRelatedField(
        slug_field='name', queryset=AdvertStatus.objects.all())
    user = PresentablePrimaryKeyRelatedField(
        queryset=User.objects.all(),
        presentation_serializer=UserSerializerBrief,
        source='creator',
    )
    subscribing_users = UserSerializer(many=True, read_only=True)

    class Meta:
        model = Advert
        fields = '__all__'
Пример #16
0
class TestPresentablePrimaryKeyRelatedField(APISimpleTestCase):
    class PresentationSerializer(serializers.Serializer):
        def to_representation(self, instance):
            return {"pk": instance.pk, "name": instance.name}

    def setUp(self):

        self.queryset = MockQueryset([
            MockObject(pk=1, name='foo'),
            MockObject(pk=2, name='bar'),
            MockObject(pk=3, name='baz')
        ])
        self.instance = self.queryset.items[2]
        self.field = PresentablePrimaryKeyRelatedField(
            queryset=self.queryset,
            presentation_serializer=self.PresentationSerializer)

    def test_representation(self):
        representation = self.field.to_representation(self.instance)
        expected_representation = self.PresentationSerializer(
            self.instance).data
        assert representation == expected_representation
Пример #17
0
class UserMeSerializer(UserSerializer):

    answers = AnswerSerializer(many=True)
    one_liners = OneLinerSerializer(many=True)
    projects = PresentablePrimaryKeyRelatedField(
        queryset=Project.objects.all(),
        presentation_serializer=ProjectSerializer,
        many=True)

    class Meta:
        model = User
        fields = [
            "id",
            "first_name",
            "last_name",
            "image",
            "timezone",
            "projects",
            "answers",
            "one_liners",
            "birth_date",
            "phone_number",
        ]
Пример #18
0
class DonationPageFullDetailSerializer(serializers.ModelSerializer):

    styles = PresentablePrimaryKeyRelatedField(
        queryset=Style.objects.all(),
        presentation_serializer=StyleInlineSerializer,
        read_source=None,
        allow_null=True,
        required=False,
    )
    revenue_program = PresentablePrimaryKeyRelatedField(
        queryset=RevenueProgram.objects.all(),
        presentation_serializer=RevenueProgramListInlineSerializer,
        read_source=None,
        allow_null=False,
        required=True,
    )
    template_pk = serializers.IntegerField(allow_null=True, required=False)

    graphic = serializers.ImageField(allow_empty_file=True,
                                     allow_null=True,
                                     required=False)
    header_bg_image = serializers.ImageField(allow_empty_file=True,
                                             allow_null=True,
                                             required=False)
    header_logo = serializers.ImageField(allow_empty_file=True,
                                         allow_null=True,
                                         required=False)

    graphic_thumbnail = HyperlinkedSorlImageField("300",
                                                  source="graphic",
                                                  read_only=True)
    header_bg_image_thumbnail = HyperlinkedSorlImageField(
        "300", source="header_bg_image", read_only=True)
    header_logo_thumbnail = HyperlinkedSorlImageField("300",
                                                      source="header_logo",
                                                      read_only=True)

    organization_is_nonprofit = serializers.SerializerMethodField(
        method_name="get_organization_is_nonprofit")
    stripe_account_id = serializers.SerializerMethodField(
        method_name="get_stripe_account_id")
    currency = serializers.SerializerMethodField(method_name="get_currency")
    organization_country = serializers.SerializerMethodField(
        method_name="get_organization_country")
    allow_offer_nyt_comp = serializers.SerializerMethodField(
        method_name="get_allow_offer_nyt_comp")

    benefit_levels = serializers.SerializerMethodField(
        method_name="get_benefit_levels")

    def get_organization_is_nonprofit(self, obj):
        return obj.organization.non_profit

    def get_stripe_account_id(self, obj):
        if self.context.get("live"):
            return obj.organization.stripe_account_id

    def get_currency(self, obj):
        return obj.organization.get_currency_dict()

    def get_organization_country(self, obj):
        return obj.organization.address.country

    def get_allow_offer_nyt_comp(self, obj):
        if not self.context.get("live", False):
            return obj.revenue_program.allow_offer_nyt_comp

    def get_benefit_levels(self, obj):
        if obj.revenue_program:
            benefit_levels = obj.revenue_program.benefitlevel_set.all()
            serializer = BenefitLevelDetailSerializer(benefit_levels,
                                                      many=True)
            return serializer.data

    class Meta:
        model = DonationPage
        fields = "__all__"
        validators = [
            ValidateFkReferenceOwnership(fk_attribute="styles"),
            ValidateFkReferenceOwnership(fk_attribute="revenue_program"),
            UniqueTogetherValidator(queryset=DonationPage.objects.all(),
                                    fields=["revenue_program", "slug"]),
        ]

    def _update_related(self, related_field, related_model, validated_data,
                        instance):
        pk_field = f"{related_field}_pk"
        if pk_field in validated_data and validated_data[pk_field] is None:
            setattr(instance, related_field, None)
        elif pk_field in validated_data:
            try:
                related_instance = related_model.objects.get(
                    pk=validated_data[pk_field])
                setattr(instance, related_field, related_instance)
            except related_model.DoesNotExist:
                raise serializers.ValidationError({
                    related_field:
                    "Could not find instance with provided pk."
                })

    def _check_against_soft_deleted_slugs(self, validated_data):
        new_slug = validated_data.get(settings.PAGE_SLUG_PARAM, None)
        if new_slug and DonationPage.objects.deleted_only().filter(
                slug=new_slug).exists():
            raise serializers.ValidationError(
                {settings.PAGE_SLUG_PARAM: [UNIQUE_PAGE_SLUG]})

    def _create_from_template(self, validated_data):
        """
        Given a template pk, find template and run model method make_page_from_template.
        Returns DonationPage instance
        Throws ValidationError if template is somehow missing.
        """
        try:
            template_pk = validated_data.pop("template_pk")
            template = Template.objects.get(pk=template_pk)
            return template.make_page_from_template(validated_data)
        except Template.DoesNotExist:
            raise serializers.ValidationError(
                {"template": ["This template no longer exists"]})

    def create(self, validated_data):
        self._check_against_soft_deleted_slugs(validated_data)
        if "template_pk" in validated_data:
            return self._create_from_template(validated_data)
        return super().create(validated_data)

    def update(self, instance, validated_data):
        self._update_related("styles", Style, validated_data, instance)
        return super().update(instance, validated_data)