DRF-фильтр поисков в HTML-формах

Я использую Django 3.05, Django Rest Framework 3.11.0, Python 3.7

Задний план

Я установил модель безопасности на уровне объектов, чтобы гарантировать User может только читать / записывать данные в Organisation или Venueк которому у них есть доступ. Это контролируется черезOrganisationMembership отображение User к Organisation.

Чтобы создать или обновить Venue пользователь должен быть назначен Organisation.

Все это работает через API Django Rest Framework, когда используется способ доступа моего приложения. Это требует небольшой настройки, но дает желаемые разрешения. Однако я также использую HTML-формы DRF для тестирования, и я не могу найти какой-либо механизм для изменения QuerySet, чтобы ограничить доступ к именам организаций в раскрывающемся списке.

Поэтому в раскрывающемся списке неправильно отображается Совершенно секретно. Organisation данные, к которым мне не разрешено OrganisationMember

                                   +-----------+--------------+
                                   |  Raw Data | HTML Form    |
+----------------------------------------------+              +
|                                                             |
|   Organisation:  v☑︎ Org 2 - I have access (McDonald's)     v |
|                  v  Org 1 - I have access (Burger King)   v |
|                  v  Org 3 - I should not see (Top Secret) v |
+-------------------------------------------------------------+

Снимок экрана здесь 1 Примечание атрибуты на снимке экрана отличаются для упрощения

Проблема

Есть ли способ применить фильтры к автоматически генерируемым раскрывающимся спискам в HTML-формах Django Rest Framework?

Я понимаю, что это взаимодействие в HTML можно отключить в производственной среде, но я не хочу рисковать.

Код и вывод

Вывод API

локальный хост / API / организации

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 2,
        "name": "Org 2 - I have access",
        "code": "McDonalds",
    },
    {
        "id": 1,
        "name": "Org 1 - I have access",
        "code": "Burger King",
    }
]

Note: Organisation ID 3 is not returned (correct)

locahost/api/venues/

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 48,
        "address": "1 High Street, London",
        "capacity": "200",
        "organisation": 2
    },
    {
        "id": 49,
        "address": "18 High Street, London",
        "capacity": "140",
        "organisation": 1
    }
}

Note: Venue ID 50 from Organisation ID 3 is not returned (correct)

CODE

models.py

class Organisation(models.Model):
    name = models.CharField(max_length=100)

    # confirm this user permitted to see Organisation
    def permitted(self, obj, user):
        print(user)
        c = Organisation.objects.filter(
            pk=obj.pk,
            organisationmember__reg_user__user=user).count()
        return c


class Venue(models.Model):
    address =      models.CharField(max_length=200)
    capacity =     models.InterField()
    organisation = models.ForeignKey(Organisation, on_delete=models.CASCADE)

    # confirm this user permitted to see Organisation Venues
    def permitted(self, obj, user):
        c = Venue.objects.filter(
            pk=obj.pk,
            organisation__organisationmember__reg_user__user=user).count()
        return c


# User Django User security via RegUser to store email address (and others)
class RegUser(model.Model):
    user =          models.OneToOneField('auth.User', on_delete=models.CASCADE)
    email =         models.EmailField(max_length=100, blank=False, unique=True)


# Permission to view/edit if RegUser is a member of Organisation
class OrganisationMember(model.Model):

    organisation =  models.ForeignKey(Organisation, models.CASCADE)
    reg_user =      models.ForeignKey(RegUser, models.CASCADE)

serializer.py

class VenueSerializer(serializers.ModelSerializer):

    class Meta:
        model = Venue
        fields = '__all__'

view.py

class VenueViewSet(viewsets.ModelViewSet):

    serializer_class = VenueSerializer

    # You must be authenticated, and have permission to see this Organisation (Update, Delete)
    permission_classes = [IsAuthenticated, OrganisationPermission]

    # get queryset filtering on user's organisation membership (Get/Query)
    def get_queryset(self):
        # You may only view organisation questions to which you are an active member
        user = self.request.user
        return OrganisationQuestion.objects.filter(
            organisation__organisationmember__reg_user__user=user,
            organisation__organisationmember__status='A')

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        if user_permitted(self.request.user, serializer.validated_data["organisation"]):
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        else:
            return Response(serializer.data, status=status.HTTP_403_FORBIDDEN)

0 ответов

Другие вопросы по тегам