仅当您通过身份验证时才发布数据,并且仅使用 django-rest-framework 向您的用户发布数据

Rob*_*ins 4 django django-rest-framework

我是 Django 新手,如果这看起来很愚蠢,我很抱歉。我想仅在用户经过身份验证时才将项目添加到数据库中。

这是模型:

class SaleItems(models.Model):
    product_name = models.CharField(max_length=50)
    price = models.IntegerField()
    product_type = models.CharField(max_length=25)
    description = models.CharField(max_length=250 ,default='', blank=True)
    brand = models.CharField(max_length=25, null=True,blank=True)
    image_path = models.ImageField(upload_to='images/product_image')
    date_added = models.DateField(auto_now_add=True)
    in_stock = models.BooleanField(default=True)

    def __str__(self):
        return f"{self.product_name}, price={self.price}"


class SaleHistory(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    product = models.ForeignKey(SaleItems, on_delete=models.RESTRICT, default=None)
    date_bought = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'{self.date_bought}, {self.product}, {self.user}' 
Run Code Online (Sandbox Code Playgroud)

序列化器:

class SaleItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = SaleItems
        fields = '__all__'


class SaleHistorySerializier(serializers.ModelSerializer):
    class Meta:
        model = SaleHistory
        fields = '__all__'

Run Code Online (Sandbox Code Playgroud)

网址:

routes = routers.DefaultRouter()
routes.register('api/saleitems', SaleItemViewSet, basename='saleitem')
routes.register('api/salehistory', SaleHistoryViewSet, basename='salehistory')
urlpatterns = [ path('',include(routes.urls))

]
Run Code Online (Sandbox Code Playgroud)

最后是 api

class SaleItemViewSet(viewsets.ModelViewSet):
    queryset = SaleItems.objects.all()
    permission_classes = [permissions.AllowAny]
    serializer_class = SaleItemSerializer


class SaleHistoryViewSet(viewsets.ModelViewSet):
    # queryset = SaleHistory.objects.all()
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = SaleHistorySerializier

    def get_queryset(self):
        user = self.request.user
        return SaleHistory.objects.filter(user = user)
Run Code Online (Sandbox Code Playgroud)

所以问题是,当我发布到“api/salehistory”时,我不仅可以作为经过身份验证的用户,还可以向任何用户添加内容。(使用 knox authtoken 进行身份验证)。

举例来说,我已通过 user1 身份进行身份验证,并且拥有我的身份验证令牌。现在,我可以使用该令牌将项目添加到任何用户的 SaleHistory 模型中,这是非常不希望的。

我该如何解决这个问题?

再次对粗略的描述表示歉意。第一次在这里提问。

JPG*_*JPG 5

首先,使用meta选项user将字段设置为read_onlyread_only_fields

class SaleHistorySerializier(serializers.ModelSerializer):
    class Meta:
        model = SaleHistory
        fields = '__all__'
        read_only_fields = ("user",)
Run Code Online (Sandbox Code Playgroud)

现在,SaleHistorySerializier将不接受来自现场的数据user

然后,您需要重写该类perform_create(...)的方法SaleHistoryViewSet

class SaleHistoryViewSet(viewsets.ModelViewSet):
    # queryset = SaleHistory.objects.all()
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = SaleHistorySerializier

    def get_queryset(self):
        return SaleHistory.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)
Run Code Online (Sandbox Code Playgroud)