在我的应用程序中,我希望在创建用户配置文件时,同时创建与用户配置文件ID关联的另一个表。
我是Django的新手。我尝试在models.py和serializers.py中的user.save()
之后创建表,方法是找到当前的user_id
然后在我想用用户个人资料创建的模型对象上调用create(owner=user_id)
,但它会给我list index out of range
。
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('id', 'email', 'name', 'password', )
extra_kwargs = {'password' : {'write_only' : True}}
def create(self, validated_data):
'''Creates and returns new user.'''
user = UserProfile(
email=validated_data['email'],
name=validated_data['name'],
)
user.set_password(validated_data['password'])
user.save()
"""here im trying to create the other tabel"""
user_id = UserProfile.objects.filter(email='email').values('id')[0]['id']
UserSessions.objects.create(owner_id=user_id)
return user
在我的model.py中:
class UserProfileManager(BaseUserManager):
"""Helps Django work with our custom user model."""
def create_user(self, email, name, password):
"""Create a new user profile object."""
if not email:
raise ValueError('Users must have an email address son!')
email = self.normalize_email(email)
user = self.model(email=email, name=name)
user.set_password(password)
user.save(using=self.db)
return user
class UserProfile(AbstractBaseUser, PermissionsMixin, models.Model):
"""Represent a user profile"""
email = models.EmailField(max_length=20, unique=True)
name = models.CharField(max_length=20)
objects = UserProfileManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
在views.py中:
class UserProfileViewSet(viewsets.ModelViewSet):
"""Handles CRU."""
serializer_class = UserProfileSerializer
queryset = UserProfile.objects.all()
authentication_classes = (TokenAuthentication,)
permission_classes = (permissions.Update_own_profile,)
filter_backends = (filters.SearchFilter,)
search_fields = ('name', 'email', 'id')
我尝试使用userprofile添加此模型:
class UserSessions(models.Model):
sessions_list_id = models.ForeignKey('UserProfile', on_delete= models.CASCADE)
owner_id = models.CharField(max_length=2, default=0)
total_Sessions = models.IntegerField(default=0)
答案 0 :(得分:1)
首先 - 欢迎来到Django社区! 我们开车吧。 关于您的术语,您不是要添加表,而是要在数据库中插入一行。
更具体地说,您正在尝试创建UserProfile
实例并将其与UserSessions
实例相关联。为此,您只需在序列化程序的create
方法中实现以下逻辑:
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('id', 'email', 'name', 'password', )
extra_kwargs = {'password' : {'write_only' : True}}
def create(self, validated_data):
'''Creates and returns new user.'''
user = UserProfile(
email=validated_data['email'],
name=validated_data['name'],
)
user.set_password(validated_data['password'])
user.save()
UserSessions.objects.create(sessions_list_id=user)
return user
请注意,我没有将UserProfile
ID传递给owner_id
,而是将整个实例传递给sessions_list_id
。 ForeignKey
字段使您可以定义表间关系,并且是要将两个实例关联的字段。因此,这也减轻了单独owner_id
字段的必要性,您似乎用它来保存所有者特定信息。此外,您应该考虑使用更为语义的命名,例如user_profile
作为键名称,并且可以像这样添加related_name
:
user_profile = models.ForeignKey('UserProfile', on_delete= models.CASCADE, related_name='sessions')
这样,您就可以获得与queryset
UserProfile
相关联的所有会话u_prof
,如下所示:
sessions = u_prof.sessions.all()
如果您想要实现自己的会话处理,Django附带了该框的权利(只是fyi)。
那就是说,有几件事让我感到困扰。由于您是Django的新手,我认为创建新的User
模型是直观的选择。 Imho,作为一个初学者,你不应该费心去实现一个自定义的用户模型,而是选择将Profile模型与你的用户相关联,这样可以处理你需要存储的其他信息:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
# any info you need to store
# in any view/ serializer, you can then access the profile like so
profile = user.profile
这也强制分离关注点,因为它允许django.contrib.auth.models.User
负责身份验证,而应用程序的模型则在Profile
模型中实现。
这样做的一个缺点是,当您希望让客户端能够更新前端的配置文件信息时,您的User
JSON表示会嵌套并引入嵌套更新的需要。但是,由于这是一种常用的技术,django rest框架的文档甚至还有一个专门的部分:see here