使用相同ID创建用户配置文件表时创建另一个表

时间:2017-12-13 07:57:19

标签: python django sqlite data-structures django-rest-framework

在我的应用程序中,我希望在创建用户配置文件时,同时创建与用户配置文件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)

1 个答案:

答案 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_idForeignKey字段使您可以定义表间关系,并且是要将两个实例关联的字段。因此,这也减轻了单独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