Django User Authentication

در رست فریم ورک دی جانگو Authentication معمولا قبل از هر request اجرا میشه و همچنین قبل از اجرا شدن هر کدیاین کنترل هویت در دو مدل در رست کنترل میشه :request.user property  : این خصیصه به یک instance از پکیج contrib.auth در کلاس User اختصاص داده میشهrequest.auth property : این خصیصه نیز برای فعالیت های اضافی در کنترل های صحت عمکلردها بکار بسته میشود بعنوان مثال این خصیصه می تواند نشان دهنده ی یک رشته فعالیت هایی باشد که طراح مشخص کرده آیا کاربرش انجام داده یا خیرخوب چگونه صحت سنجی کاربر کار می کندAuthentication Schema معمولا بصورت لیستی از کلاس ها قرار میگیرد. رست شروع می کند و به ترتیب صحت سنجی را با کلاس های لیست شده انجام می دهد و سپس request.auth and request.user  را برای اولین کلاسی که به درستی صحت سنجی شده باشد را بر میگرداند.اگر صحت سنجی کلاسی صورت نپذیرد بجای آن دو خصیصه یک کلاس بنام django.contrib.auth.models.AnonymousUser برای request.user برگشت داده شده و همچنین None به request.auth اختصاص داده میشود. ضمنا می توان این وضعیت را UNAUTHENTICATED_USER and UNAUTHENTICATED_TOKEN در settings.py مدیریت نمود.مواردی که باید تحقیق شود : فرق بین router and url در django rest framework : در اصل این روتر ها یکی از امکانات viewSet ها هستند که بر میگردد به مدلی که برنامه نویس برای توسعه ی نرم افزار خود در پیش گرفته است.زمانی که از viewset بجای view‌استفاده می نماییم می توانیم بصورت خودکار از ui درخواست ها را گرفته و با کمترین شلوغی در کد با یک روتر کلاس در ویو ست آنها را اجرا کرده و نتیجه را منعکس نماییم. در نتیجه با استفاده از این روتر کلاس ها می توانیم در restframework admin نیز این مسیر ها را مشاهده و دستکاری نماییمحالا برای اینکه از دیجانگو به درک بهتری برسم دارم این آدرس رو پیاده سازی و تست میکنم :‌خوب مثال یک لینک اشاره رو ردیف کردم :چیزی که تو این مثال اورده بود بیشتر شبیه به همون متدهای قبلی جانگو فرم بود و فقط بجای مثلا فرم یه سریالایزر از نوع مدل گذاشتمحالا میرم تو مثال دوم 

farsiTutorial 2: Requests and ResponsesFrom this point we’re going to really start covering the core of REST framework. Let’s introduce a couple of essential building blocks.Request objectsREST framework introduces a Request object that extends the regular HttpRequest, and provides more flexible request parsing. The core functionality of the Request object is the request.data attribute, which is similar to request.POST, but more useful for working with Web APIs.request.POST # Only handles form data. Only works for 'POST' method. request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods. 
farsiResponse objectsREST framework also introduces a Response object, which is a type of TemplateResponse that takes unrendered content and uses content negotiation to determine the correct content type to return to the client.return Response(data) # Renders to content type as requested by the client.
farsitatus codesUsing numeric HTTP status codes in your views doesn’t always make for obvious reading, and it’s easy to not notice if you get an error code wrong. REST framework provides more explicit identifiers for each status code, such as HTTP_400_BAD_REQUEST in thestatus module. It’s a good idea to use these throughout rather than using numeric identifiers.
farsiWrapping API viewsREST framework provides two wrappers you can use to write API views.The @api_view decorator for working with function based views.The APIView class for working with class based views.These wrappers provide a few bits of functionality such as making sure you receive Request instances in your view, and adding context to Response objects so that content negotiation can be performed.The wrappers also provide behaviour such as returning 405 Method Not Allowed responses when appropriate, and handling anyParseError exception that occurs when accessing request.data with malformed input.
farsiPulling it all togetherOkay, let’s go ahead and start using these new components to write a few views.We don’t need our JSONResponse class in views.py anymore, so go ahead and delete that. Once that’s done we can start refactoring our views slightly.from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from snippets.models import Snippet from snippets.serializers import SnippetSerializer @api_view(['GET', 'POST']) def snippet_list(request): """ List all snippets, or create a new snippet. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)Our instance view is an improvement over the previous example. It’s a little more concise, and the code now feels very similar to if we were working with the Forms API. We’re also using named status codes, which makes the response meanings more obvious.Here is the view for an individual snippet, in the views.py module.@api_view(['GET', 'PUT', 'DELETE']) def snippet_detail(request, pk): """ Retrieve, update or delete a snippet instance. """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = SnippetSerializer(snippet) return Response(serializer.data) elif request.method == 'PUT': serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)This should all feel very familiar – it is not a lot different from working with regular Django views.Notice that we’re no longer explicitly tying our requests or responses to a given content type. request.data can handle incomingjson requests, but it can also handle other formats. Similarly we’re returning response objects with data, but allowing REST framework to render the response into the correct content type for us.
farsiAdding optional format suffixes to our URLsTo take advantage of the fact that our responses are no longer hardwired to a single content type let’s add support for format suffixes to our API endpoints. Using format suffixes gives us URLs that explicitly refer to a given format, and means our API will be able to handle URLs such as http://example.com/api/items/4/.json.Start by adding a format keyword argument to both of the views, like so.def snippet_list(request, format=None):anddef snippet_detail(request, pk, format=None):Now update the urls.py file slightly, to append a set of format_suffix_patterns in addition to the existing URLs.from django.conf.urls import patterns, url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views urlpatterns = [ url(r'^snippets/$', views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail), ] urlpatterns = format_suffix_patterns(urlpatterns)We don’t necessarily need to add these extra url patterns in, but it gives us a simple, clean way of referring to a specific format.How’s it looking?Go ahead and test the API from the command line, as we did in tutorial part 1. Everything is working pretty similarly, although we’ve got some nicer error handling if we send invalid requests.We can get a list of all of the snippets, as before.http http://127.0.0.1:8000/snippets/ HTTP/1.1 200 OK ... [ { "id": 1, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly" }, { "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly" } ]We can control the format of the response that we get back, either by using the Accept header:http http://127.0.0.1:8000/snippets/ Accept:application/json # Request JSON http http://127.0.0.1:8000/snippets/ Accept:text/html # Request HTMLOr by appending a format suffix:http http://127.0.0.1:8000/snippets/.json # JSON suffix http http://127.0.0.1:8000/snippets/.api # Browsable API suffixSimilarly, we can control the format of the request that we send, using the Content-Type header.# POST using form data http --form POST http://127.0.0.1:8000/snippets/ code="print 123" { "id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly" } # POST using JSON http --json POST http://127.0.0.1:8000/snippets/ code="print 456" { "id": 4, "title": "", "code": "print 456", "linenos": false, "language": "python", "style": "friendly" }Now go and open the API in a web browser, by visiting http://127.0.0.1:8000/snippets/.BrowsabilityBecause the API chooses the content type of the response based on the client request, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a web browser. This allows for the API to return a fully web-browsable HTML representation.Having a web-browsable API is a huge usability win, and makes developing and using your API much easier. It also dramatically lowers the barrier-to-entry for other developers wanting to inspect and work with your API.See the browsable api topic for more information about the browsable API feature and how to customize it.What’s next?In tutorial part 3, we’ll start using class based views, and see how generic views reduce the amount of code we need to write. 
farsiTutorial 3: Class Based ViewsWe can also write our API views using class based views, rather than function based views. As we’ll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code DRY.
farsiRewriting our API using class based viewsWe’ll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring of views.py.from snippets.models import Snippet from snippets.serializers import SnippetSerializer from django.http import Http404 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class SnippetList(APIView): """ List all snippets, or create a new snippet. """ def get(self, request, format=None): snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) def post(self, request, format=None): serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)So far, so good. It looks pretty similar to the previous case, but we’ve got better separation between the different HTTP methods. We’ll also need to update the instance view in views.py.class SnippetDetail(APIView): """ Retrieve, update or delete a snippet instance. """ def get_object(self, pk): try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)That’s looking good. Again, it’s still pretty similar to the function based view right now.We’ll also need to refactor our urls.py slightly now we’re using class based views.from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views urlpatterns = [ url(r'^snippets/$', views.SnippetList.as_view()), url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns)Okay, we’re done. If you run the development server everything should be working just as before.
farsiUsing mixinsOne of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.The create/retrieve/update/delete operations that we’ve been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework’s mixin classes.Let’s take a look at how we can compose the views by using the mixin classes. Here’s our views.py module again.from snippets.models import Snippet from snippets.serializers import SnippetSerializer from rest_framework import mixins from rest_framework import generics class SnippetList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)We’ll take a moment to examine exactly what’s happening here. We’re building our view using GenericAPIView, and adding inListModelMixin and CreateModelMixin.The base class provides the core functionality, and the mixin classes provide the .list() and .create() actions. We’re then explicitly binding the get and post methods to the appropriate actions. Simple enough stuff so far.class SnippetDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)Pretty similar. Again we’re using the GenericAPIView class to provide the core functionality, and adding in mixins to provide the.retrieve().update() and .destroy() actions.
farsiUsing generic class based viewsUsing the mixin classes we’ve rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use to trim down our views.py module even more.from snippets.models import Snippet from snippets.serializers import SnippetSerializer from rest_framework import generics class SnippetList(generics.ListCreateAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer class SnippetDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializerWow, that’s pretty concise. We’ve gotten a huge amount for free, and our code looks like good, clean, idiomatic Django.Next we’ll move onto part 4 of the tutorial, where we’ll take a look at how we can deal with authentication and permissions for our API.
farsiTutorial 4: Authentication & PermissionsCurrently our API doesn’t have any restrictions on who can edit or delete code snippets. We’d like to have some more advanced behavior in order to make sure that:Code snippets are always associated with a creator.Only authenticated users may create snippets.Only the creator of a snippet may update or delete it.Unauthenticated requests should have full read-only access.
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish
farsienglish

دیدگاهتان را بنویسید