DjangoRestFramework-如何更新模型中的字段

时间:2018-08-23 16:38:54

标签: python django django-models django-rest-framework django-views

我正在使用Django用户模型,并且还使用自己的个人档案模型扩展了其他数据。当我要更新个人档案模型中的用户数据时,由于所有用户ID,用户名,电子邮件,密码驻留在用户模型中,而需要更新的字段位于配置文件模型中。我使用了这种方法,它所做的只是获取输入并显示响应,但在整体查看用户数据时未显示任何更改

models.py

class Profile(models.Model):
    user = models.OneToOneField(User,related_name='profile',on_delete=models.CASCADE)
    location = models.CharField(max_length=30,blank=True)
    friends_count = models.PositiveIntegerField(default=0)
    profile_pic = models.FileField(upload_to='profile_pics/',blank=True,null=True)

    def natural_key(self):
        return (self.user.username,)

views.py

class UserCreateAPIViewSet(viewsets.ModelViewSet,mixins.UpdateModelMixin):
    """"A View which handles  Creating  and Updating User Profile"""
    serializer_class = UserProfileCreateSerializer
    queryset = User.objects.all()

    authentication_classes = (TokenAuthentication,)
    permission_classes = (permissions.UpdateOwnProfile,)

    filter_backends = (filters.SearchFilter,)
    search_fields = ('username','email',)

class UserUpdateAPI(generics.GenericAPIView,mixins.UpdateModelMixin):
    """Update User Profile Data"""
    permission_classes = (permissions.UpdateOwnProfile,)
    authentication_classes = (TokenAuthentication,)
    queryset = Profile.objects.all()
    serializer_class = ProfileUpdateSerializer

    def put(self,request,*args,**kwargs):
        return self.partial_update(request,*args,**kwargs)

urls.py

url(r'^user-update/(?P<pk>\d+)/$',views.UserUpdateAPI.as_view(),name="user-update"),
router = DefaultRouter()
router.register(r'profile',views.UserCreateAPIViewSet)

serializers.py

class UserProfileCreateSerializer(serializers.ModelSerializer):
    """"A serializer for user data request"""
    location = serializers.CharField(source='profile.location')
    friends_count = serializers.IntegerField(source='profile.friends_count',read_only=True)
    profile_pic = serializers.FileField(source='profile.profile_pic',allow_empty_file=True,allow_null=True)


    class Meta:
        model = User
        fields = (
            'pk',
            'username',
            'email',
            'password',
            'location',
            'friends_count',
            'profile_pic',
        )
        extra_kwargs = {
            'password':{'write_only':True},
            'friends_count':{'read_only':True},
        }

    def create(self, validated_data):
        """"Create and return a new User"""


        user = User(
            email = validated_data['email'],
            username = validated_data['username']
        )

        user.set_password(validated_data['password'])

        user.save()

        return user

class ProfileUpdateSerializer(serializers.ModelSerializer):
    """A serializer for updating user data"""
    class Meta:
        model = Profile
        fields = ('location','profile_pic')

1 个答案:

答案 0 :(得分:1)

好像您想从AbstractBaseUser扩展(请参见下面的代码),将其用作UserProfileCreateSerializer

class UserProfileCreateSerializer(serializers.ModelSerializer):
    """"A serializer for user data request"""
    location = serializers.CharField(source='profile.location')
    friends_count = serializers.IntegerField(source='profile.friends_count',read_only=True)
    profile_pic = serializers.FileField(source='profile.profile_pic',allow_empty_file=True,allow_null=True)


    class Meta:
        model = Profile
        fields = (
            'pk',
            'username',
            'email',
            'password',
            'location',
            'friends_count',
            'profile_pic',
        )
        extra_kwargs = {
            'password':{'write_only':True},
            'friends_count':{'read_only':True},
        }

    def create(self, validated_data):
         """"Create and return a new User"""


        user = Profile(
             email = validated_data['email'],
             username = validated_data['username']
        )

        user.set_password(validated_data['password'])

        user.save()

        return user

class ProfileUpdateSerializer(serializers.ModelSerializer):
    """A serializer for updating user data"""
    class Meta:
        model = Profile
        fields = ('location','profile_pic')

然后从AbstractBaseUser中的models.py延伸:

from __future__ import unicode_literals

from django.db import models
from django.core.mail import send_mail
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils.translation import ugettext_lazy as _

from .managers import ProfileManager

class Profile(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    username = models.CharField(_('first name'), max_length=30, blank=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
    is_active = models.BooleanField(_('active'), default=True)
    location = models.CharField(max_length=30,blank=True)
    friends_count = models.PositiveIntegerField(default=0)
    profile_pic =  models.FileField(upload_to='profile_pics/',blank=True,null=True)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

    def get_full_name(self):
        '''
        Returns the first_name plus the last_name, with a space in between.
        '''
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        '''
        Returns the short name for the user.
        '''
        return self.first_name

    def natural_key(self):
        return (self.username,)

    def email_user(self, subject, message, from_email=None, **kwargs):
        '''
        Sends an email to this User.
        '''
        send_mail(subject, message, from_email, [self.email], **kwargs)

然后在与managers.py相同的目录中创建一个名为models.py的文件:

from django.contrib.auth.base_user import BaseUserManager

class ProfileManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)

要打包所有这些,您需要将其添加到settings.py文件中:

AUTH_USER_MODEL = 'app.Profile'

也不要忘记在使用$ python manage.py runserver之前重新运行所有数据库迁移。