Exemplo n.º 1
0
    def update(self, instance, validated_data):
        """
        Update the profile, including nested fields.

        Raises:
        errors.AccountValidationError: the update was not attempted because validation errors were found with
            the supplied update
        """
        language_proficiencies = validated_data.pop("language_proficiencies", None)

        # Update all fields on the user profile that are writeable,
        # except for "language_proficiencies" and "social_links", which we'll update separately
        update_fields = set(self.get_writeable_fields()) - set(["language_proficiencies"]) - set(["social_links"])
        for field_name in update_fields:
            default = getattr(instance, field_name)
            field_value = validated_data.get(field_name, default)
            setattr(instance, field_name, field_value)

        # Update the related language proficiency
        if language_proficiencies is not None:
            instance.language_proficiencies.all().delete()
            instance.language_proficiencies.bulk_create([
                LanguageProficiency(user_profile=instance, code=language["code"])
                for language in language_proficiencies
            ])

        # Update the user's social links
        social_link_data = self._kwargs['data']['social_links'] if 'social_links' in self._kwargs['data'] else None
        if social_link_data and len(social_link_data) > 0:
            new_social_link = social_link_data[0]
            current_social_links = list(instance.social_links.all())
            instance.social_links.all().delete()

            try:
                # Add the new social link with correct formatting
                validate_social_link(new_social_link['platform'], new_social_link['social_link'])
                formatted_link = format_social_link(new_social_link['platform'], new_social_link['social_link'])
                instance.social_links.bulk_create([
                    SocialLink(user_profile=instance, platform=new_social_link['platform'], social_link=formatted_link)
                ])
            except ValueError as err:
                # If we have encountered any validation errors, return them to the user.
                raise errors.AccountValidationError({
                    'social_links': {
                        "developer_message": u"Error thrown from adding new social link: '{}'".format(text_type(err)),
                        "user_message": text_type(err)
                    }
                })

            # Add back old links unless overridden by new link
            for current_social_link in current_social_links:
                if current_social_link.platform != new_social_link['platform']:
                    instance.social_links.bulk_create([
                        SocialLink(user_profile=instance, platform=current_social_link.platform,
                                   social_link=current_social_link.social_link)
                    ])

        instance.save()

        return instance
Exemplo n.º 2
0
    def _update_social_links(self, instance, requested_social_links):
        """
        Update the given profile instance's social links as requested.
        """
        try:
            new_social_links = []
            deleted_social_platforms = []
            for requested_link_data in requested_social_links:
                requested_platform = requested_link_data['platform']
                requested_link_url = requested_link_data['social_link']
                validate_social_link(requested_platform, requested_link_url)
                formatted_link = format_social_link(requested_platform,
                                                    requested_link_url)
                if not formatted_link:
                    deleted_social_platforms.append(requested_platform)
                else:
                    new_social_links.append(
                        SocialLink(user_profile=instance,
                                   platform=requested_platform,
                                   social_link=formatted_link))

            platforms_of_new_social_links = [
                s.platform for s in new_social_links
            ]
            current_social_links = list(instance.social_links.all())
            unreplaced_social_links = [
                social_link for social_link in current_social_links
                if social_link.platform not in platforms_of_new_social_links
            ]
            pruned_unreplaced_social_links = [
                social_link for social_link in unreplaced_social_links
                if social_link.platform not in deleted_social_platforms
            ]
            merged_social_links = new_social_links + pruned_unreplaced_social_links

            instance.social_links.all().delete()
            instance.social_links.bulk_create(merged_social_links)

        except ValueError as err:
            # If we have encountered any validation errors, return them to the user.
            raise errors.AccountValidationError({
                'social_links': {
                    "developer_message":
                    u"Error when adding new social link: '{}'".format(
                        text_type(err)),
                    "user_message":
                    text_type(err)
                }
            })