Как фильтровать/скрывать поля в HTML-форме django rest framework, используя аутентифицированного пользователя
Я создал две модели:
- модель посылки (пакета),
- модель "полки", на которую могут быть назначены посылки.
class Parcel(models.Model):
owner = models.ForeignKey(get_user_model(), on_delete=models.PROTECT)
name = models.CharField(max_length=100, blank=False)
contents = models.TextField(blank=False, validators=[MaxLengthValidator(1500)])
size = models.CharField(max_length=50, blank=True, validators=[package_size_validator])
weight = models.PositiveIntegerField(blank=True, null=True)
contact = models.CharField(max_length=50, blank=True)
creation_date = models.DateTimeField(auto_now_add=True)
last_modification = models.DateTimeField(auto_now=True)
code = models.CharField(max_length=30, unique=True, blank=False)
def __str__(self):
return f'Parcel: {self.code}, {self.owner}, {self.name}'
class ParcelShelf(models.Model):
owner = models.ForeignKey(get_user_model(), on_delete=models.PROTECT)
name = models.CharField(max_length=100, blank=False)
creation_date = models.DateTimeField(auto_now_add=True)
last_modification = models.DateTimeField(auto_now=True)
parcels = models.ManyToManyField('Parcel', blank=True, related_name='shelf_parcel')
def __str__(self):
return f'ParcelShelf: {self.owner}, {self.name}'
Я пришел к решению, при котором зарегистрированный пользователь может видеть только свои посылки и полки. У меня проблема с отношением "многие-ко-многим", когда посылки могут быть добавлены на полки. Я хочу прийти к решению, при котором зарегистрированный пользователь может добавлять на полку только те посылки, владельцем, создателем которых он является. Это будет лучше выглядеть на картинках.
Все посылки, созданные пользователем t2@t2.com (id пользователя = 17): список пакетов
Теперь представление, когда пользователь t2@t2.com хочет создать полку: shelf list. Видны все пакеты, а доступны должны быть только те, которые создал пользователь t2@t2.com. Код для сериализатора:
class ParcelShelfSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
parcels = serializers.HyperlinkedRelatedField(many=True, read_only=False, view_name='parcels_detail_view',
# queryset=Parcel.objects.filter(owner=17)
queryset=Parcel.objects.all()
)
class Meta:
model = ParcelShelf
fields = ('id', 'owner', 'name', 'creation_date', 'last_modification', 'parcels')
Ниже показано изображение, на котором доступны только пакеты для данного, вошедшего в систему пользователя: список полки
Код для сериализатора:
class ParcelShelfSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
parcels = serializers.HyperlinkedRelatedField(many=True, read_only=False, view_name='parcels_detail_view',
queryset=Parcel.objects.filter(owner=17)
# queryset=Parcel.objects.all()
)
class Meta:
model = ParcelShelf
fields = ('id', 'owner', 'name', 'creation_date', 'last_modification', 'parcels')
Я дошел до точки, где "решение" находится в аргументе "queryset".
Все пользователи: queryset=Parcel.objects.all()
Зарегистрированный пользователь: queryset=Parcel.objects.filter(owner=17)
Проблема в том, что это жестко закодировано, а должно быть что-то вроде: (owner=request.user). К сожалению, я не знаю, как добиться этого в сериализаторе. Я просмотрел другие подобные темы, но не нашел решения, как использовать метод запроса в поле сериализатора.
Кроме того, код в представлениях:
class ParcelsShelfList(generics.ListCreateAPIView):
# queryset = ParcelShelf.objects.all()
serializer_class = ParcelShelfSerializer
def get_queryset(self):
user = self.request.user
if bool(user and user.is_staff and user.is_admin):
return ParcelShelf.objects.all()
else:
return ParcelShelf.objects.filter(owner=user)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)