无法注册用户类型错误:禁止直接分配到相关集合的反面。改为使用searches.set()

2024-09-30 06:29:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经在Django REST API中设置了模型、序列化器和视图集,以将搜索记录分配给特定用户,并将所有相关用户的搜索与他们在用户模型中的记录相关联。这一切都很好,但是当我尝试创建一个新用户时,我现在得到了TypeError错误消息(在这个问题的主题行中)。我在下面列出了相关的模型、序列化程序和视图集。谁能看一下,告诉我哪里出了问题?任何帮助都将不胜感激

用户序列化程序:

class UserSerializer(serializers.ModelSerializer):
    searches = serializers.PrimaryKeyRelatedField(many=True, queryset=SearchHistoryModel.objects.all())

    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'password', 'searches')
        extra_kwargs = {'email': {
            'required': True,
            'validators': [UniqueValidator(queryset=User.objects.all())]
        }}

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        Token.objects.create(user=user)
        return user

用户视图集:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.AllowAny]

搜索模式:

class SearchHistoryModel(models.Model):
    """
    Stores each user's search submission
    """
    created_date = models.DateTimeField(auto_now_add=True)
    owner = models.ForeignKey(User, related_name='searches', on_delete=models.CASCADE)
    cpu_component_name = models.CharField(max_length=10, blank=False)
    cpu_subcomponent_name = models.CharField(max_length=50, blank=False)
    motherboard_name = models.CharField(max_length=20, blank=False)
    gpu_component_name = models.CharField(max_length=10, blank=True, null=True)
    gpu_subcomponent_name = models.CharField(max_length=50, blank=True, null=True)
    gpu_subcomponent_quantity = models.PositiveIntegerField(default=0)
    ram_component_name = models.CharField(max_length=15, blank=True, null=True)
    ram_component_quantity = models.PositiveIntegerField(default=0)
    ssd_component_name = models.CharField(max_length=15, blank=True, null=True)
    ssd_component_quantity = models.PositiveIntegerField(default=0)
    hdd_component_name = models.CharField(max_length=20, blank=True, null=True)
    hdd_component_quantity = models.PositiveIntegerField(default=0)
    optical_drive_name = models.CharField(max_length=15, blank=True, null=True)

    class Meta:
        verbose_name = 'Search'
        verbose_name_plural = 'Searches'
        ordering = ['owner', 'created_date']

    def __str__(self):
        return '{}\'s search choices'.format(self.owner)

搜索序列化程序:

class SearchHistorySerializer(serializers.ModelSerializer):
    """
    Serializes the user's search history data passed into the SearchHistoryModel
    Associates each search with the relevant user
    """
    owner = serializers.ReadOnlyField(source='owner.username')

    class Meta:
        model = SearchHistoryModel
        fields = (
            'id', 'created_date', 'owner', 'cpu_component_name', 'cpu_subcomponent_name',
            'motherboard_name', 'gpu_component_name', 'gpu_subcomponent_name',
            'gpu_subcomponent_quantity', 'ram_component_name', 'ram_component_quantity',
            'ssd_component_name', 'ssd_component_quantity', 'hdd_component_name',
            'hdd_component_quantity', 'optical_drive_name'
        )

搜索视图集:

class SearchHistoryViewSet(viewsets.ModelViewSet):
    queryset = SearchHistoryModel.objects.all()
    serializer_class = SearchHistorySerializer
    permission_classes = [permissions.IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

Tags: 用户nametrueobjectsmodelslengthmaxquantity
1条回答
网友
1楼 · 发布于 2024-09-30 06:29:57

user = User.objects.create_user(**validated_data)中,validated_data包含一个searches值,该值是一个id

但实际上,ForeignKey在另一个意义上是:在Searches模型中,并且引用User实例,而不是相反

要将用户链接到搜索,不是在UserDB表中写入id,而是在Searches中写入用户id

class UserSerializer(serializers.ModelSerializer):
    (...)

    def create(self, validated_data):
        # Extract the value from 'validated_data'
        search_ids = validated_data.pop('searches', None)

        user = User.objects.create_user(**validated_data)
        Token.objects.create(user=user)

        # Update existing search instances
        for search_id in search_ids:
           Search.objects.filter(id=search_id).update(owner=user)

        return user

相关问题 更多 >

    热门问题