ジャンゴRESRframework
ミックスイン、ビューセットとに関連して使用ルータ
Mixins
5つのクラスがあります。
CreateModelMixin
ListModelMixin
RetrieveModelMixin
UpdateModelMixin
DestroyModelMixin
彼らは、対応する操作、書き込みロジックは同じコードを繰り返して行く必要はないされ、それらを使用することの利点を削除し、データベース、検索、変更の増加に対応しており、それぞれがあるためmixins
、内部で論理的対応書かれている、のみ設定する必要がありますそれqueryset
とserializer_class
それ
ViewSet
また、5種類あります。
ViewSetMixin
ViewSet
GenericViewSet
ReadOnlyModelViewSet
ModelViewSet
一般的な言葉だけを使用する必要がありGenericViewSet
、十分に、それは継承ViewSetMixin
し、generics.GenericAPIView
それを設定することで、我々はすべて知っている機能queryset
とserializer_class
フォーカスと性質、ViewSetMixin
それは上書きされますas_view
、これは私たちが登録することを可能にする、メソッドをurl
使用している方法がある、非常に簡単になりinitialize_request
、この方法は、主にされたaction
プロパティの割り当て、このプロパティは、動的に設定されているserializer
とpermission
巨大な利点がありますが!
だから、〜書きAPIView
、次のようにコードを
from rest_framework import mixins
from rest_framework import viewsets
class XXXViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = Model.objects.all()
serializer_class = ModelSerializer
次のステップは、設定することですurl
from appname.views import XXXViewSet
models = XXXViewSet.asview({
'get': 'list',
'post': 'create'
})
urlpattrtns = [
url(r'apiAddress/$',models, name="models"),
あなたがすることができるようset
にバインドするために要求しlist
、上記の方法、post
要求がバインドされているcreat
方法で、あなたは実際には、上記の構成、それらを書き換えるに行く必要はありませんurl
方法も容易になることがあるのでrouter
〜それをデビューさせるであろう
from rest_framework.routers import DefaultRouter
from appname.views import XXXViewSet
router = DefaultRouter()
router.register(r'apiAddress', XXXViewSet, base_name='apiAddress')
urlpattrtns = [
# 这个已经不需要了
# url(r'apiAddress/$',models, name="models"),
url(r'^', include(router.urls)),
]
後でに追加しましたurl
唯一の時間必要がrouter
内側のリストに登録され、urlpattrtns
リストは変更する必要はありません。これが完了するRESTful API
創造、合理的な試合になることができmixins
、ViewSet
及びrouter
S 3、あなたは超高速の多数を開発することができますRESTful API
!
ジャンゴRESTframeworkフィルタリングを使用します
単純なフィルタ機能、例えば、ユーザクエリのリストは、ファンの数のみが100より大きい返します。
class XXXViewSet(mixins.ListModelMixin,mixins.CreateModelMixin,viewsets.GenericViewSet):
serializer_class = ModelSerializer
def get_query(self):
fans_nums = self.request.quer_params.get("fans_min",0)
if fans_nums:
return User.object.filter(fans_num__gt=int(fans_min))
return User.objects.all()
この方法では、書き込みフィルタフィールドがあまりにも多く、繰り返される冗長なコードの多くを書くために必要であれば、上記必要ですので、する必要がありますdjango-filter
行うこと
最初は、インストールされる
pip install django-filter
、その後django-filter
に追加INSTALLED_APPS
行きます
コードは以下の通りであります:
from rest_framework import mixins
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from django.contrib.auth import get_user_model
User = get_user_model()
class UserViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer_class = ModelSerializer
filter_backends = (DjangoFilterBackend,)
# 设置过滤字段,这里设置过滤用户的名字和粉丝数
filter_fields = ('name', 'fans_num')
次に、ブラウザ開く127.0.0.1:8000
あなたは、対応するノードビューを見ることができますが、(このメソッドは、ルーティング登録を使用する必要があります)
この方法では、フィルタインタフェースに表示されますfilter_fields = ('name', 'fans_num')
フィルター内部のフィールド条件を設定しました
新しいですfilter.py
import django_filters
from django.contrib.auth import get_user_model
User = get_user_model()
class UserFilter(django_filters.rest_framework.FilterSet):
min_fans_num = django_filter.NumberFilter(name='fans_num', lookup_expr='gte')
max_fans_num = django_filters.NumberFilter(name='fans_num', lookup_expr='lt')
name = django_filters.CharFilter(name='name',lookup_expr='icontains')
class Meta:
model = User
fields = ['name', 'min_fans_num', 'max_fans_num']
そして、コードが変更されました前に
from .filter import UserFilter
class UserViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer_class = ModelSerializer
filter_backends = (DjangoFilterBackend,)
filter_class = UserFilter
ユーザ名によるフィルタは、その後、実際には、SearchFilter
また、2行のコードを使用して実施することができる十分です
filter_backends = (DjangoFilterBackend, SearchFilter)
serch_fields = ("name",)
より強力な設定もあります。
The search behavior may be restricted by prepending various characters to the search_fields.
'^' Starts-with search.
'=' Exact matches.
'@' Full-text search. (Currently only supported Django's MySQL backend.)
'$' Regex search.
For example:
search_fields = ('=username', '=email')
並べ替えもありfilter
、ファンの利用者の数に応じて、たとえば、我々は(昇順または降順)ソートしたいです、:
カスタムのページング
from rest_framework.pagination import PageNumberPagination
class UsersPagination(PageNumberPagination):
# 指定每一页的个数
page_size = 10
# 可以让前端来设置page_szie参数来指定每页个数
page_size_query_param = 'page_size'
# 设置页码的参数
page_query_param = 'page'
class UserViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
# 设置分页的class
pagination_class = UsersPagination
だから、数行のコードを取得するには、リターンでは、json
次と前のリンク上のリンクの合計数を追加しました。
私たちがコードを確認する前に、UserViewSet
そこにこのクラス、単にコードの7行を書き、それが完了しています
- ユーザーのリスト
create
ユーザー- ページング
- 検索
- 心配
- ソート
指定したユーザーのために特定の情報を取得したい場合は、これらの機能は、直接の後継するmixins.RetrieveModelMixin
直接良い仕事をします...「」
証明機関
例えば、缶を使用するにはログインするユーザーを必要とするいくつかのAPI関数があり
、私はこのブログを削除するかの例を、私は著者が削除できることを確認する必要があります
ユーザーがログインしていることを確認します
from rest_framework.permissions import IsAuthenticated
class XXXViewSet(mixins.CreateModelMixin, mixins.DestroyModelMixin):
permission_classes = (IsAuthenticated,)
あなたは、動作を確認する必要がある場合permission
permission.py
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, object):
if request.method in permissions.SAFE_METHODS:
return True
return object.user == request.user
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
##使用JWTユーザ認証モード
- インストール
pip install djangorestframework-jwt
url.py
設定
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
...
url(r'^api-token-auth/', obtain_jwt_token),
...
]
- 所望で
jwt
認証ViewSet
クラスの内部に設けられています
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import SessionAuthentication
class XXXViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
プラスSessionAuthenticationは、サイト上のデバッグに便利です。
二つの方法は、サインイン今すぐサインアップ:
- ユーザ登録は、ログインページのログインにジャンプすることが許可された後、
- 登録後、ユーザーは自動的に彼を助けるためにログインしている
し、我々は他の操作を行う必要はありません。最初のケースを、第二の場合は、我々はユーザー登録後に返す必要がありますjwttoken
前に、フィールドなので、2つの手順を実行します。
フィールドが返されているのでmixins
、私たちは良い仕事を助けるために、私たちはリターンフィールドを変更するために、対応するメソッドを書き換える必要があり
確認する必要がdjangorestframework-jwt
生成見つけるために、ソースコードをjwt token
メソッドを
from rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler
class UserViewSet(CreateModelMixin, RetrieveModelMixin,UpdateModelMixin,viewsets.GenericViewSet):
# 重写create方法
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = self.perform_create(serializer)
# 在新建用户保存到数据库之后
tmp_dict = serializer.data
# 生成JWT Token
payload = jwt_payload_handler(user)
tmp_dict['token'] = jwt_encode_handler(payload)
headers = self.get_success_headers(serializer.data)
return Response(tmp_dict, status=status.HTTP_201_CREATED, headers=headers)
もっとJWT関連の操作は、ドキュメントを表示することができます
ダイナミックserializers
の使用前に、これは言っaction
プロパティを簡単に達成することができます
class UserViewSet(CreateModelMixin, RetrieveModelMixin,UpdateModelMixin,viewsets.GenericViewSet):
# 这个就不需要了
#serializer_class = XXXSerializer
def get_serializer_class(self):
if self.action == 'create':
return XXXSerializer
elif self.action == 'list':
return XXXSerializer
return XXXSerializer
いくつかの実用的なSerializer fields
例として、私は(ユーザー)をアップロードしたい、この記事を公開するid
関連付ける機能と、この記事で、私たちは、アップロードするためにフロントを持つことはできません
serializer.py
class XXXSerializer(serializers.ModelSerializer):
# user默认是当前登录的user
user = serializers.HiddenField(
default = serializers.CurrentUserDefault()
)
返された論理的なフィールドは、より複雑ながある場合は、()は、例えば、行われserializer.SerializerMethodFieldを使用することができます。
class XXXSerializer(serializers.ModelSerializer):
xxx = serializer.SerializerMethodField()
# 把逻辑写在get_的前缀加xxx(字段名),然后返回
def get_xxx(self, obj):
# 完成你的业务逻辑
return
カスタムユーザー認証は
Django
、ログイン伝わってくるusername
とpassword
ログを行いますが、現在多くのウェブサイトやapp
ユーザ認証をカスタマイズする必要性に電話番号がアカウントとして使用されるように、この時間:
from django.contrib.auth.backends import ModelBackend
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username)|Q(mobile=username))
# 验证密码是否正确
if user.check_password():
return user
except Exception as e:
return None
あなたがバックグラウンドで見た場合に、プレーンテキストで保存するときに直接ModelSerializerが明確に保存されているので、ユーザー登録時には、この問題を解決するために、次のとおりです。
serializer.py
class UserRegSerializer(serializers.ModelSerializer):
#重写create方法
def create():
user = super(UserRegSerializer,self).create(validated_data=validated_data)
user.set_password(validated_data["password"])
user.save()
return user
セマフォ、あるいはまたジャンゴ解決することができます
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
User = get_user_model()
@receiver(post_save, sender=User)
def create_user(sender, instance=None, created=False, **kwargs):
if created:
password = instance.password
instance.set_password(password)
instance.save()
その後も、コンフィギュレーション内app.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals