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
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/
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
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')
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
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
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
- In view_base, the product list page is implemented through the native view of django itself.
- Self-serialization - model_to_dict method - using Serializer - JSonresponse
- api view generics - viewsets