Я пытаюсь сделать API-интерфейс из чего-то вроде Reddit.Я хочу убедиться, что тот, кто создает пост (модель Post
) в определенном субреддите, является членом этого субреддита (модель субреддита - Sub
).Вот мое последнее усилие, которое работает, но кажется довольно небрежным, и сериализатор для некоторого контекста.
Пост permissions.py
class IsMemberOfSubOrReadOnly(BasePermission):
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS:
return True
elif request.data:
# prevent creation unless user is member of the sub
post_sub_pk = get_pk_from_link(request.data['sub'])
user = request.user
user_sub_pks = [sub.pk for sub in user.subs.all()]
if not (post_sub_pk in user_sub_pks):
return False
return True
Post serializers.py
from .models import Post
from redditors.models import User
from subs.models import Sub
class PostSerializer(serializers.HyperlinkedModelSerializer):
poster = serializers.HyperlinkedRelatedField(
view_name='user-detail',
#queryset=User.objects.all(),
read_only=True
)
sub = serializers.HyperlinkedRelatedField(
view_name='sub-detail',
queryset=Sub.objects.all()
)
class Meta:
model = Post
fields = ('url', 'id', 'created', 'updated', 'title', 'body',
'upvotes', 'sub', 'poster')
Проблема с этим подходом состоит в том, что, поскольку 'sub' является гиперссылкойRelatedField на сериализаторе Post
, я получаю обратноиз request.data['sub']
- просто URL-адрес гиперссылки на строку.Затем у меня есть функция get_pk_from_link
, которая использует регулярные выражения для чтения pk с конца URL.Затем я могу использовать это, чтобы получить нужную модель и проверить вещи.Было бы неплохо, если бы существовал более прямой способ доступа к модели Sub
, участвующей в запросе.
Я попытался найти поля доступных аргументов и не могу найтиспособ добраться до объекта Sub
напрямую.Есть ли способ получить доступ к объекту модели Sub
через URL-адрес гиперссылки?
Я также решил эту проблему, просто используя валидатор поля сериализатора (не показан выше), но мне интересно знать, как это сделать также.Может быть, это просто плохая идея, и если так, пожалуйста, дайте мне знать, почему.