# Path: rest_framework_extensions/serializers.py
# def get_fields_for_partial_update(opts, init_data, fields, init_files=None):
#     opts = opts.model._meta.concrete_model._meta
#     partial_fields = list((init_data or {}).keys()) + \
#         list((init_files or {}).keys())
#     concrete_field_names = []
#     for field in get_model_opts_concrete_fields(opts):
#         if not field.primary_key:
#             concrete_field_names.append(field.name)
#             if field.name != field.attname:
#                 concrete_field_names.append(field.attname)
#     update_fields = []
#     for field_name in partial_fields:
#         if field_name in fields:
#             model_field_name = getattr(
#                 fields[field_name], 'source') or field_name
#             if model_field_name in concrete_field_names:
#                 update_fields.append(model_field_name)
# 
#     # recurse on nested fields of same ('*') instance
#     for k, v in (init_data or {}).items():
#         if isinstance(v, dict) and k in fields and fields[k].source == '*':
#             recursive_fields = get_fields_for_partial_update(
#                 opts, v, fields[k].fields.fields)
#             update_fields.extend(recursive_fields)
# 
#     return sorted(set(update_fields))
# 
# Path: tests_app/tests/unit/serializers/serializers.py
# class CommentSerializer(drf_serializers.PartialUpdateSerializerMixin,
#                         serializers.ModelSerializer):
#     title_from_source = serializers.CharField(source='title', required=False)
# 
#     class Meta:
#         model = CommentModel
#         fields = (
#             'id',
#             'user',
#             'users_liked',
#             'title',
#             'text',
#             'attachment',
#             'title_from_source'
#         )
# 
# class UserSerializer(drf_serializers.PartialUpdateSerializerMixin,
#                      serializers.ModelSerializer):
#     class Meta:
#         model = UserModel
#         fields = (
#             'name',
#             'comments'
#         )
# 
# class CommentSerializerWithGroupedFields(CommentSerializer):
#     text_content = CommentTextSerializer(source='*')
# 
#     class Meta(CommentSerializer.Meta):
#         fields = (
#             'id',
#             'user',
#             'users_liked',
#             'attachment',
#             'title_from_source',
#             'text_content'
#         )
# 
# class CommentSerializerWithAllowedUserId(CommentSerializer):
#     user_id = serializers.IntegerField()
# 
#     class Meta(CommentSerializer.Meta):
#         fields = ('user_id',) + CommentSerializer.Meta.fields
# 
# Path: tests_app/tests/unit/serializers/models.py
# class UserModel(models.Model):
#     name = models.CharField(max_length=20)
# 
# class CommentModel(models.Model):
#     user = models.ForeignKey(
#         UserModel,
#         related_name='comments',
#         on_delete=models.CASCADE,
#     )
#     users_liked = models.ManyToManyField(UserModel, blank=True)
#     title = models.CharField(max_length=20)
#     text = models.CharField(max_length=200)
#     attachment = models.FileField(
#         upload_to='test_serializers', blank=True, null=True, max_length=500)
#     hidden_text = models.CharField(max_length=200, blank=True, null=True)


from django.test import TestCase
from django.core.files.base import ContentFile
from rest_framework_extensions.serializers import get_fields_for_partial_update
from .serializers import CommentSerializer, UserSerializer, \
    CommentSerializerWithGroupedFields, CommentSerializerWithAllowedUserId
from .models import UserModel, CommentModel
        self.assertEqual(fresh_instance.title, 'goodbye')
        self.assertEqual(fresh_instance.text, 'world')
        self.assertEqual(fresh_instance.hidden_text, None)

    def test_should_use_list_of_fields_to_update_from_arguments_if_it_passed(self):
        data = {
            'title': 'goodbye',
            'text': 'moon'
        }
        serializer = CommentSerializer(instance=self.get_comment(), data=data, partial=True)
        self.assertTrue(serializer.is_valid())
        serializer.save(**{'update_fields': ['title']})
        fresh_instance = self.get_comment()
        self.assertEqual(fresh_instance.title, 'goodbye')
        self.assertEqual(fresh_instance.text, 'world')

    def test_should_not_use_field_attname_for_update_fields__if_attname_not_allowed_in_serializer_fields(self):
        another_user = UserModel.objects.create(name='vova')
        data = {
            'title': 'goodbye',
            'user_id': another_user.id
        }
        serializer = CommentSerializer(
            instance=self.get_comment(), data=data, partial=True)
        self.assertTrue(serializer.is_valid())
        serializer.save()
        fresh_instance = self.get_comment()
        self.assertEqual(fresh_instance.user_id, self.user.id)

    def test_should_use_field_attname_for_update_fields__if_attname_allowed_in_serializer_fields(self):

# Path: rest_framework_extensions/serializers.py
# def get_fields_for_partial_update(opts, init_data, fields, init_files=None):
#     opts = opts.model._meta.concrete_model._meta
#     partial_fields = list((init_data or {}).keys()) + \
#         list((init_files or {}).keys())
#     concrete_field_names = []
#     for field in get_model_opts_concrete_fields(opts):
#         if not field.primary_key:
#             concrete_field_names.append(field.name)
#             if field.name != field.attname:
#                 concrete_field_names.append(field.attname)
#     update_fields = []
#     for field_name in partial_fields:
#         if field_name in fields:
#             model_field_name = getattr(
#                 fields[field_name], 'source') or field_name
#             if model_field_name in concrete_field_names:
#                 update_fields.append(model_field_name)
# 
#     # recurse on nested fields of same ('*') instance
#     for k, v in (init_data or {}).items():
#         if isinstance(v, dict) and k in fields and fields[k].source == '*':
#             recursive_fields = get_fields_for_partial_update(
#                 opts, v, fields[k].fields.fields)
#             update_fields.extend(recursive_fields)
# 
#     return sorted(set(update_fields))
# 
# Path: tests_app/tests/unit/serializers/serializers.py
# class CommentSerializer(drf_serializers.PartialUpdateSerializerMixin,
#                         serializers.ModelSerializer):
#     title_from_source = serializers.CharField(source='title', required=False)
# 
#     class Meta:
#         model = CommentModel
#         fields = (
#             'id',
#             'user',
#             'users_liked',
#             'title',
#             'text',
#             'attachment',
#             'title_from_source'
#         )
# 
# class UserSerializer(drf_serializers.PartialUpdateSerializerMixin,
#                      serializers.ModelSerializer):
#     class Meta:
#         model = UserModel
#         fields = (
#             'name',
#             'comments'
#         )
# 
# class CommentSerializerWithGroupedFields(CommentSerializer):
#     text_content = CommentTextSerializer(source='*')
# 
#     class Meta(CommentSerializer.Meta):
#         fields = (
#             'id',
#             'user',
#             'users_liked',
#             'attachment',
#             'title_from_source',
#             'text_content'
#         )
# 
# class CommentSerializerWithAllowedUserId(CommentSerializer):
#     user_id = serializers.IntegerField()
# 
#     class Meta(CommentSerializer.Meta):
#         fields = ('user_id',) + CommentSerializer.Meta.fields
# 
# Path: tests_app/tests/unit/serializers/models.py
# class UserModel(models.Model):
#     name = models.CharField(max_length=20)
# 
# class CommentModel(models.Model):
#     user = models.ForeignKey(
#         UserModel,
#         related_name='comments',
#         on_delete=models.CASCADE,
#     )
#     users_liked = models.ManyToManyField(UserModel, blank=True)
#     title = models.CharField(max_length=20)
#     text = models.CharField(max_length=200)
#     attachment = models.FileField(
#         upload_to='test_serializers', blank=True, null=True, max_length=500)
#     hidden_text = models.CharField(max_length=200, blank=True, null=True)


# Path: tests_app/tests/unit/serializers/tests.py
from django.test import TestCase
from django.core.files.base import ContentFile
from rest_framework_extensions.serializers import get_fields_for_partial_update
from .serializers import CommentSerializer, UserSerializer, \
    CommentSerializerWithGroupedFields, CommentSerializerWithAllowedUserId
from .models import UserModel, CommentModel

        self.assertEqual(fresh_instance.title, 'goodbye')
        self.assertEqual(fresh_instance.text, 'world')
        self.assertEqual(fresh_instance.hidden_text, None)

    def test_should_use_list_of_fields_to_update_from_arguments_if_it_passed(self):
        data = {
            'title': 'goodbye',
            'text': 'moon'
        }
        serializer = CommentSerializer(instance=self.get_comment(), data=data, partial=True)
        self.assertTrue(serializer.is_valid())
        serializer.save(**{'update_fields': ['title']})
        fresh_instance = self.get_comment()
        self.assertEqual(fresh_instance.title, 'goodbye')
        self.assertEqual(fresh_instance.text, 'world')

    def test_should_not_use_field_attname_for_update_fields__if_attname_not_allowed_in_serializer_fields(self):
        another_user = UserModel.objects.create(name='vova')
        data = {
            'title': 'goodbye',
            'user_id': another_user.id
        }
        serializer = CommentSerializer(
            instance=self.get_comment(), data=data, partial=True)
        self.assertTrue(serializer.is_valid())
        serializer.save()
        fresh_instance = self.get_comment()
        self.assertEqual(fresh_instance.user_id, self.user.id)

    def test_should_use_field_attname_for_update_fields__if_attname_allowed_in_serializer_fields(self):

        another_user = UserModel.objects.create(name='vova')