Django REST API и проблема Django_filter - PullRequest
0 голосов
/ 15 октября 2019

У меня проблема с rest_framework.viewsets.ReadOnlyModelViewSet.

class ProductFilter(filters.FilterSet):
    meat_type = filters.CharFilter(lookup_expr='slug__iexact')
    category = filters.CharFilter(lookup_expr='slug__iexact')

    class Meta:
        model = Product
        fields = {
            'price': ['gte', 'lte'],
        }
        ordering_fields = ['price', ]


class ProductViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filterset_class = ProductFilter

    @action(methods=['get'], detail=False)
    def get_products(self, request):
        products = self.get_queryset().order_by('-created')
        serializer = self.get_serializer_class()(products, many=True)
        print('SHOW IT')
        if len(products) == 0:
            return Response(status=status.HTTP_204_NO_CONTENT)

        return Response(serializer.data, status=status.HTTP_200_OK)

Моя проблема в том, что print в get_products не работает, но код дает хороший результат с объектами фильтров. Мои URL:

router = routers.DefaultRouter()
router.register('', views.ProductViewSet)

urlpatterns = [
    path('shop/', include(router.urls))

]

Тесты:

class TestViews(TestCase):

    def setUp(self):
        self.client = Client()
        self.url = "/api/shop/"
        self.search_url = "/api/shop/?price__lte={}&price__gte={}&meat_type={}&category={}"

        self.category1 = Category.objects.create(name='cattest1',
                                                 slug='cattest1')
        self.category2 = Category.objects.create(name='cattest2',
                                                 slug='cattest2')
        self.meat_type1 = MeatType.objects.create(name='meattest1',
                                                  slug='meattest1')
        self.meat_type2 = MeatType.objects.create(name='meattest2',
                                                  slug='meattest2')
        self.product1 = Product.objects.create(category=self.category1,
                                               meat_type=self.meat_type2,
                                               name='prodtest1',
                                               slug='prodtest1',
                                               price=50)
        self.product2 = Product.objects.create(category=self.category1,
                                               meat_type=self.meat_type1,
                                               name='prodtest2',
                                               slug='prodtest2',
                                               price=75)
        self.product3 = Product.objects.create(category=self.category2,
                                               meat_type=self.meat_type2,
                                               name='prodtest3',
                                               slug='prodtest3',
                                               price=20)
        self.product4 = Product.objects.create(category=self.category2,
                                               meat_type=self.meat_type1,
                                               name='prodtest4',
                                               slug='prodtest4',
                                               price=150)

    def test_get_products_all(self):
        response = self.client.get(self.url)
        self.assertEqual(200, response.status_code)
        self.assertEqual(4, len(response.data))

    def test_get_products_no_content(self):
        Product.objects.all().delete()
        response = self.client.get(self.url)
        self.assertEqual(204, response.status_code)

    def test_product_greater_than(self):
        response = self.client.get(self.search_url.format(
            "", "55", "", ""
        ))
        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))

Тест test_get_products_no_content не пройден с ошибкой: assertionError: 204! = 200 .
У кого-нибудь естьидея? Спасибо за любой ответ
Магнус

РЕДАКТИРОВАТЬ
Создал эту функцию, передает хорошие данные для фильтрации.
DICT {'price__lte': '50', 'price__gte': '100 ',' meat_type ':' wieprzowina '}
Но у меня проблема, когда я указываю это в качестве аргумента фильтра. Получена ошибка:
недопустимый литерал для int () с основанием 10: 'wieprzowina' . Он пытается изменить строку на число, но я не знаю, почему.

    def get_queryset(self):

        filter_params = self.request.query_params
        filter_params_dict = {k: str(v) for (k, v) in filter_params.dict().items()
                              if v is not None and str(v) != ""}
        print('DICT', filter_params_dict)
        queryset = Product.objects.filter(**filter_params_dict)
        return queryset

РЕДАКТИРОВАТЬ 2:

class Product(models.Model):
    category = models.ForeignKey(Category,
                                 related_name='products',
                                 on_delete=models.CASCADE)
    meat_type = models.ForeignKey(MeatType,
                                  on_delete=models.CASCADE)
    name = models.CharField(max_length=150,
                            db_index=True)
    slug = models.SlugField(max_length=150,
                            db_index=True)
    image = models.ImageField(upload_to='products/%Y/%m/%d',
                              default='no-image.png')
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('price',)
        index_together = (('id', 'slug'),)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('shop:detail',
                       args=[self.category.slug, self.id, self.slug])

1 Ответ

0 голосов
/ 15 октября 2019

Вы используете неверный URL, вы должны использовать этот URL для своего пользовательского действия:

/ api / shop / get_products /

URL, который вы используетето есть / api / shop / будет вызывать действие списка по умолчанию для набора просмотра, а не ваше пользовательское действие, и поэтому вы всегда получаете 200 кодов состояния

Подробнее о наборе представлений можно прочитать здесь: ViewSets

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...