我正在使用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')
答案 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
之前重新运行所有数据库迁移。