6- vue django restful framework to create fresh supermarkets - complete the list of goods page (below)

Keywords: Django REST Python Attribute

request and response in drf

drf encapsulates django request and response in one layer.

Browser requests are encapsulated by drf to extend the standard http request

REST framework's Request class extends the standard HttpRequest, adding support for REST framework's flexible request parsing and request authentication

Extended on the basic httpRequest. Support for flexible request parsing and request authentication of REST framework has been added.

Request parsing parses the data sent by users

  • Data puts data from users'post s and files into data
  • Including all parsed content, file, non-file.
  • Not only does it parse what comes from the post method. Other things like put patch will help us parse.

.query_params

Inside is the parameter passed by the get request? min=10

.parsers

There are many types of data passed by users. For example, file. json from post. Character string.

Use drf to provide us with a variety of parsers

Any type of data can receive and call parser to specify the corresponding parser

Authentication

The. user in authentication can get the current user. auth returns some additional information

response returns to you based on the parameters passed from your front desk.

For example, if the front desk asks to return to json, it will return to json. Return html if you want to return html that browsers can parse

mark

response also supports template_render returning html

drf filter

The filtering function provided by drf is simple and fast.

GenericAPIView inherited from GenericViewSet has a method that we can override for our filtering

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    //Merchandise List Page
    """
    # queryset is an attribute
    # good_viewset.queryset is accessible
    # The function must call the good_viewset.get_queryset() function
    # If you have get_queryset below. So this one above is not needed.
    # queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    queryset = Goods.objects.all()

    def get_queryset(self):
        # Price over 100
        price_min = self.request.query_params.get('price_min', 0)
        if price_min:
            self.queryset = Goods.objects.filter(shop_price__gt=price_min)
        return self.queryset

Here in the drf used by the teacher, the queryset is placed inside the get function and returned.
After my testing, the new version must be as shown in the code above.

Possible errors:

    assert queryset is not None, '`base_name` argument not specified, and could ' \
AssertionError: `base_name` argument not specified, and could not automatically determine the name from the viewset, as it does not have a `.queryset` attribute.

It can be said that the error message is clearly written. We lack a queryset attribute.

Possible warnings:

 UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'goods.models.Goods'> QuerySet.
  paginator = self.django_paginator_class(queryset, page_size)

This is because we did not add a specified sort for our return data.

self.queryset = Goods.objects.filter(shop_price__gt=price_min).order_by('-add_time')

Adds a specified sort to eliminate warnings.

Visit: http://127.0.0.1:8000/goods/?page=2&price_min=100

You can see the filtering effect.

Optimization of filtration

Even so, we still feel that this filtering is too troublesome.

We also need to get the parameters and judge whether the parameters exist. After the parameters exist, they are converted into int (I did not turn).

Although it seems that there is not much code at present, if there are many filtering parameters, the filtering will become more complex.

filter using drf

http://www.django-rest-framework.org/api-guide/filtering/

mark

Traditional filters are similar to our filters in the xadmin background.

  • The behavior of searchFilter is search behavior.
  • Sorted filter

There are three kinds of filters commonly used in list pages, namely, accurate filtering of traditional fields of list pages, search filtering, and sorting.

DjangoFilterBackend

pip install django-filter
  • Add to the list of installed app s after installation.
django_filters,
  • Add settings. Since the default settings are usually set automatically.
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
  • Start using, import in first

goods/views.py

from django_filters.rest_framework import DjangoFilterBackend

Official examples:

class UserListView(generics.ListAPIView):
    ...
    filter_backends = (DjangoFilterBackend,)

We need to set it in our view

mark
filter_backends = (DjangoFilterBackend,)

Now that we have decided to use djangofilter, we can avoid the get_queryset method. Annotate

  • Setting the fields we need to filter

Official examples:

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('category', 'in_stock')

Our practice:

    # Setting the fields we need to filter
    filter_fields = ('name', 'shop_price')
mark

You can see that there is an additional filter on the top right of our page. This is an exact equivalent of a filter.

?name=&shop_price=100

We want to search vaguely. Or search for an interval.

https://django-filter.readthedocs.io/en/master/

Not only does he have a filter that satisfies drf, he also uses it

filter_class

We can customize our own filter class, and we can customize the filter class.

Create new filters.py in the goods directory

# -*- coding:utf-8 _*-
__author__ = 'mtianyan'
__date__ = '2018/03/03 00:44'

from django_filters import rest_framework as filters
from goods.models import Goods


class GoodsFilter(filters.FilterSet):
    """
    //Filters of commodities
    """
    # Specify the field and the behavior on the field, greater than or equal to shop_price
    price_min = filters.NumberFilter(name="shop_price", lookup_expr='gte')
    price_max = filters.NumberFilter(name="shop_price", lookup_expr='lte')

    class Meta:
        model = Goods
        fields = ['price_min', 'price_max']
    # Setting up DjangoFilterBackend of Three Common Filters
    filter_backends = (DjangoFilterBackend,)

    # Set the filter class to our custom class
    filter_class = GoodsFilter

Note out: filter_fields, by this time our filter_fields have expired

mark

The filter does not have a definite button because of inheritance errors. import rest_framework as filters of rf should be inherited

Search and ranking of drf

We don't necessarily use its own filtering method in this class. You can also customize our filtering methods, which will be discussed later.

https://code.ziqiangxuetang.com/django/django-queryset-api.html

Django QuerySetAPI

Fuzzy query

    # Behavior: The name contains a character, and the character is case-insensitive
    name = filters.CharFilter(name="name", lookup_expr="icontains")

    class Meta:
        model = Goods
        fields = ['price_min', 'price_max', 'name']

Configure SearchFilter in drf

http://www.django-rest-framework.org/api-guide/filtering/#searchfilter

from rest_framework import filters

    # Setting up DjangoFilterBackend, SearchFilter of Three Common Filters
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)

It's important to note that the filters in the code above are not filters in django, but in restframe. Otherwise you will make a mistake.

    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
AttributeError: module 'django_filters.rest_framework.filters' has no attribute 'SearchFilter'

After configuring search_fields, configure our search_fields

    # Set up our search field
    search_fields = ('name', 'goods_brief', 'goods_desc')

search_fields.

  • ^ Starts-with search.
  • = Exact matches.
  • @ Full-text search. (Currently only supported Django's MySQL backend.)
  • $ Regex search.

Starting with the current field value is equivalent to precise field filtering. Full text search. Regular expression search

search_fields = ('=username', '=email')

By default, the search parameter is named 'search', but this may be overridden with the SEARCH_PARAM setting.

The default search parameter is

mark

search. SEARCH_PARAM can be overwritten in the settings for customization.

You can configure different precision searches for multiple fields. For example, name is an exact search, and profile is a fuzzy search.

OrderingFilter supports sorting

    # Setting up DjangoFilterBackend, SearchFilter of Three Common Filters
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    # Set sort
    ordering_fields = ('sold_num', 'add_time')

In general full-text search, the real fuzzy query is done using elastic Search.

but this may by overridden with the ORDERING_PARAM setting.

Rewrite the order parameter. Implement the specified parameter values in url

Not only data acquisition, data submission and login validation can be operated in this interface.

summary

  1. In view_base, the product list page is implemented through the native view of django itself.
  2. Self-serialization - model_to_dict method - using Serializer - JSonresponse
  3. api view generics - viewsets

Posted by avvllvva on Sat, 05 Jan 2019 14:06:09 -0800