Как получить вложенный URL для OneToOne Relationship? - PullRequest
0 голосов
/ 07 октября 2018

Я немного застрял в следующей ситуации.Я хочу создать REST API для приложения корзины покупок, используя Django Rest Framework, однако из-за устаревших требований мне нужно работать с вложенными URL-адресами.

В общем, у меня есть два ресурса AppUsers и Carts.Оба ресурса доступны по умолчанию / appUsers / и / carts / endpoints.Затем я попытался использовать вложенные маршрутизаторы, чтобы получить подробное представление корзины для конкретного пользователя с адресом / appUsers / app_user_pk / cart / вместо / carts / pk /, поскольку каждый AppUser в любом случае может иметь только одну корзину.

Вот мои настройки:

models.py

class AppUser(models.Model):
    _id = models.AutoField(primary_key=True)

    class Meta:
        default_related_name = 'app_users'


class Cart(models.Model):
    app_user = models.OneToOneField(
        'AppUser',
        on_delete=models.CASCADE,
        related_query_name='cart',
    )

    class Meta:
        default_related_name = 'carts'

    def __str__(self):
        return "{user} cart".format(user=self.app_user._id)

serializers.py

class AppUserSerializer(serializers.HyperlinkedModelSerializer):
    cart = serializers.HyperlinkedIdentityField(view_name='cart-detail')

    class Meta:
        model = AppUser
        fields = '__all__'


class CartSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Cart
        fields = '__all__'

views.py

class AppUserViewSet(viewsets.ModelViewSet):
    """
    Model viewset for AppUser model
    """
    queryset = AppUser.objects.all()
    serializer_class = AppUserSerializer


class CartViewSet(viewsets.ModelViewSet):
    """
    List all carts, or create new / edit existing product.
    """
    queryset = Cart.objects.all()
    serializer_class = CartSerializer

    def get_queryset(self):
        if 'app_user_pk' in self.kwargs:
            return Cart.objects.filter(app_user=self.kwargs['app_user_pk'])
        return Cart.objects.all()

urls.py

router = DefaultRouter()

router.register(r'appUsers', views.AppUserViewSet)
router.register(r'carts', views.CartViewSet)
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^appUsers/(?P<app_user_pk>[0-9]+)/cart/$', views.CartViewSet.as_view({'get': 'retrieve'}), name='cart-detail'),
]

Однако я не могу заставить его работать, всякий раз, когда я пробую что-то новое, я сталкиваюсь с другой проблемой.Итак, мне было интересно, как лучше всего решить эту задачу?

По сути, я просто хочу иметь подробное описание корзины для одной корзины, которую AppUser может иметь в / appUsers / app_user_pk / cart /

РЕШЕНИЕ:

Я использовал принятый ответ для решения вышеуказанной проблемы.Кроме того, у меня был другой ModelViewSet, расположенный по адресу / appUsers / app_user_pk / cart / products, который я затем зарегистрировал с помощью NestedDefaultRouter из drf-nested-router в корзине / products, например:

cart_products_router = routers.NestedDefaultRouter(router, r'appUsers', lookup='app_user')
cart_products_router.register(r'cart/products', views.CartProductViewSet, base_name='cartproduct')

1 Ответ

0 голосов
/ 07 октября 2018

Вы можете создать собственный метод до AppUserViewSet:

class AppUserViewSet(viewsets.ModelViewSet):
    """
    Model viewset for AppUser model
    """
    queryset = AppUser.objects.all()
    serializer_class = AppUserSerializer

    @action(detail=True)
    def cart(self, request, pk):
        obj = Cart.objects.get(app_user_id=pk)
        serializer = CartSerializer(obj)
        return Response(serializer.data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...