【问题标题】:Create another table when user profile table gets created with same ID使用相同 ID 创建用户配置文件表时创建另一个表
【发布时间】:2018-05-27 01:13:41
【问题描述】:

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

【问题讨论】:

  • 更重要的是 - 为什么您需要 UserSession 才能拥有与您的 UserProfile 相同的 id
  • 我需要一种方法来获取与特定 UserProfile 相关联的 UserSession,这样当客户发送他的 id 时我可以找到两者。

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


【解决方案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')

这使您可以获取与UserProfile u_prof 关联的所有会话的queryset,如下所示:

sessions = u_prof.sessions.all()

如果您想实现自己的会话处理,Django 提供了相应的功能(仅供参考)。

也就是说,有几件事让我感到困扰。由于您是 Django 新手,我认为创建新的 User 模型是您的直观选择。恕我直言,作为初学者,您不应该为实现自定义 User 模型而烦恼,而应采用将 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 framework 的文档甚至为此专门提供了一个部分:see here

【讨论】:

  • 非常感谢,热烈欢迎和很好的回答!我懂了。关于自定义模型,正如您建议的那样,我肯定会使用默认配置文件模型。感谢您指出这一点。
猜你喜欢
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多