更新与Django Rest中的外键相关的记录

时间:2015-10-29 12:12:50

标签: django django-rest-framework

我想以任何方式更新与外键相关或相关的记录。我知道如何更新单个模型记录,但在相关模型的情况下我无法做到这一点。

我的模特:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    subject = models.ManyToManyField('Subjects')
    phone = models.CharField(max_length=20)
    address = models.TextField()

    def __unicode__(self):
        return self.user.username

class Subjects(models.Model):
    name = models.CharField(max_length=100)
    code = models.IntegerField()


    def __unicode__(self):
        return self.name

我的序列化器:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (
                'id',
                'first_name',
                'username',
                'email',
                'is_active',
            )

class SubjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subjects
        fields = (
                'name',
                'code',
            )

class UserProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    subject = SubjectSerializer(many=True)

    class Meta:
        model = UserProfile
        fields = (
                'user',
                'subject',
                'phone',
                'address',
            )

观点:

class UserProfileList(viewsets.ModelViewSet):
    serializer_class = UserProfileSerializer

    queryset = UserProfile.objects.all()

网址

router.register(r'api/user/profile', UserProfileList)

我可以看到第一条记录为/api/user/profile/1/但是当我尝试从可浏览的休息Api 更新记录时,它会给我错误 { {1}}

修改:

我想使用user with same username already exist.更新UserProfile模型。简单地创建新记录,更新现有记录并删除。

1 个答案:

答案 0 :(得分:0)

您确实有一个约束用户名,无法再次创建。 您需要通过更改验证程序UserSerializer.username来删除它。 确保不要通过打印序列化程序来删除其他约束:

>>> print(UserSerializer())
>>> UserSerializer():
    id = IntegerField(label='ID', read_only=True)
    first_name = CharField(allow_blank=True, max_length=30, required=False)
    username = CharField(help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, validators=[<django.core.validators.RegexValidator object>, <UniqueValidator(queryset=User.objects.all())>])
    email = EmailField(allow_blank=True, label='Email address', max_length=254, required=False)
    is_active = BooleanField(help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', label='Active', required=False)

您可以注意到,我们在用户名上有一个UniqueValidator以及一个RegexValidator

你需要改变课程:

from django.core import validators
from django.utils.translation import ugettext_lazy as _

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (
            'id',
            'first_name',
            'username',
            'email',
            'is_active',
        )
        extra_kwargs = {
            'username': {
                'validators': [
                    validators.RegexValidator(
                        r'^[\w.@+-]+$',
                        _('Enter a valid username. This value may contain only '
                        'letters, numbers ' 'and @/./+/-/_ characters.')
                ),]
            }
        }

请注意,此处的验证器取自该字段的Django定义(https://github.com/django/django/blob/master/django/contrib/auth/models.py#L309

现在,如果再次打印序列化程序,您应该会看到唯一约束被删除:

>>> print(UserSerializer())
>>> UserSerializer():
    id = IntegerField(label='ID', read_only=True)
    first_name = CharField(allow_blank=True, max_length=30, required=False)
    username = CharField(help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, validators=[<django.core.validators.RegexValidator object>])
    email = EmailField(allow_blank=True, label='Email address', max_length=254, required=False)
    is_active = BooleanField(help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', label='Active', required=False)