#django #django-rest-framework
#джанго #django-rest-фреймворк #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}'
сериализаторы:
class SaleItemSerializer(serializers.ModelSerializer):
class Meta:
model = SaleItems
fields = '__all__'
class SaleHistorySerializier(serializers.ModelSerializer):
class Meta:
model = SaleHistory
fields = '__all__'
URL-адреса:
routes = routers.DefaultRouter()
routes.register('api/saleitems', SaleItemViewSet, basename='saleitem')
routes.register('api/salehistory', SaleHistoryViewSet, basename='salehistory')
urlpatterns = [ path('',include(routes.urls))
]
и, наконец, 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)
итак, проблема в том, что когда я отправляю сообщение в ‘api / salehistory’, я могу добавлять контент любому пользователю не только как аутентифицированный пользователь.
(используя knox authtoken для аутентификации).
Скажем, например, я аутентифицирован как пользователь1, и у меня есть свой токен аутентификации. Теперь я могу использовать этот токен для добавления элементов в модель SaleHistory для любого пользователя, что очень нежелательно.
как я могу это решить?
еще раз извините за грубое описание. впервые задаю вопрос здесь.
Комментарии:
1. Почему вы используете viewet вместо apiview?
2. Я не эксперт, но я думаю, что вы можете создать
perform_create
функцию типаget_queryset
и убедиться в этой функции, что созданная история продаж принадлежит аутентифицированному пользователю.3. честно говоря, я не знаю. Но то, что я понял из viewsets, позволяет упростить URL conf или что-то в этом роде. должен ли я использовать apiview?.
Ответ №1:
Сначала установите для user
поля значение только для чтения, используя read_only_fields
параметр meta
class SaleHistorySerializier(serializers.ModelSerializer):
class Meta:
model = SaleHistory
fields = '__all__'
read_only_fields = ("user",)
Теперь 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)