Djangular

یکی از دغدغه های من آوردن AngularJS به Django بوده و این موضوع کاملا با Djangular پوشش داده میشه :)))

مراحل کار :

pip install django-angular
INSTALLED_APPS = (
    ...
    'djangular',
    ...
)

STATIC_ROOT and STATIC_URL فراموش نشود و سپس جرای دستور :

python manage.py collectstatic

دستور بالا مسیر استاتیک را با فایل های مورد نیاز دیجنگولار بروز رسانی میکند یعنی باید مسیر مورد نظر مجوز ویرایش را داشته باشد هاا

البته دیجانگولار هیچ مدل داده ای ندارد و بدون تغییرات بانک اطلاعاتی می تواند عملیات خود را ادامه دهد

 Integrate AngularJS with Django

XMLHttpRequest

معمولا در وب سایت ها درخواست های آژادکسی هدر خود را بصورت زیر ارسال میکنند :

X-Requested-With: XMLHttpRequest

این هدر است که به دیجانگو امکان میدهد تا بفهمد :

request.is_ajax()

حالا برای اینکه این امکان رو فراهم کنیم کافیگ زیر را برای appمون منویسیم

var my_app = angular.module('MyApp').config(function($httpProvider) {
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

 Template tags

برای اینکه تگ های آنگولار با تگ های دیجاگو گیژ نزنن کد زیر رو میزنیم :

var my_app = angular.module('MyApp').config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('{$');
    $interpolateProvider.endSymbol('$}');
});

راستی این رو هم اضافه کنید :

<script src="{% static 'djangular/js/django-angular.min.js' %}" type="text/javascript"></script>

و سپس :

var my_app = angular.module('myApp', [/* other dependencies */, 'ng.django.forms']);

حالا تو لینک زیر یه مثال خوب هست که بهش توجه کنیم :

https://github.com/jrief/django-angular/tree/master/examples

Integrate a Django form with an AngularJS model

هر گاه می خواهیم forms.Form رو ببریم بسمت AngularJS Env برای ما لازم است که به یک صفحه ی رندر شده ی AngularJSی دسترسی پیدا کنیم

ng-model="model_name"

where model_name corresponds to the named field from the declared form class. :)))

کد نمونه :

در نظر بگیریم که یک کلاس فرم ساده دیجانگو داریم که از یک فرم ورود متن ساده تشکیل شده است و ما می خواهیم دهنش رو با آوردن به djangularjs کلاس NgModelFormMixin سرویس کنیم

from django import forms
from django.utils import six
from djangular.forms import NgDeclarativeFieldsMetaclass, NgModelFormMixin

class ContactForm(six.with_metaclass(NgDeclarativeFieldsMetaclass, NgModelFormMixin, forms.Form)):
    subject = forms.CharField()
    # more fields ...

در مثال بالا همونطور که معلومه فرم ما از دیجانگو فرم برگفته شده است و در عوض میشه اینطوری هم نوشتش :

from djangular.forms import NgModelFormMixin, NgForm

class MyValidatedForm(NgModelFormMixin, NgForm):
    # members as above

و همینطور اینگونه :

from djangular.forms import NgModelFormMixin, NgModelForm

class MyValidatedForm(NgModelFormMixin, NgModelForm):
    class Meta:
         model = Article

    # fields as usual

حالا آبجکت های اینطوری رندر میشن :

<input id="id_subject" type="text" name="subject" ng-model="subject" />

حالا یه مثال کامل :

مثال زیر نشان دهنده ی ارسال داده هاست بوسیله ی انگولارجی اس کنترولر. و ویروی دیجانگو که قراره کنترل کننده ی اون باشه به شکل زیره :

from django.views.generic import TemplateView

class ContactFormView(TemplateView):
    template = 'contact.html'

    def get_context_data(self, **kwargs):
        context = super(ContactFormView, self).get_context_data(**kwargs)
        context.update(contact_form=ContactForm())
        return context

و حالا تمپلیت contact.html

<form ng-controller="MyFormCtrl" name="contact_form">
    {{contact_form}}
    <button ng-click="submit()">Submit</button>
</form>

یه کمی هم جاوا اسکریپت قاطیش می کنیم :

my_app.controller('MyFormCtrl', function($scope, $http) {
    $scope.submit = function() {
        var in_data = { subject: $scope.subject };
        $http.post('/url/of/your/contact_form_view', in_data)
            .success(function(out_data) {
                // do something
            });
    }
});

و اما اینکه <form> نیازی به method or action نداره و از طریق success کنترلر ارسال میشه و تمام ابعاد قضیه رو شامل ارسال و پاسخ رو در نظر میگیره مثل ارسال ارورهای اعتبارسنجی شده و …

به طور معمول form view میبایست داده های پست شده رو از طریق POST دریافت کنه در حالی که AngularJS دیتا رو از طریق multipart/form-data or application/x-www-form-urlencoded نمی تونه ارسال کنه البته به خاطر یه سری مسایل دیکودینگ هااا

برای جواب داده به فرم هم بهتره از کد زیر استفاده بشه :

import json
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseBadRequest

class ContactFormView(TemplateView):
    # use ‘get_context_data()’ from above

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(ContactFormView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        if not request.is_ajax():
            return HttpResponseBadRequest('Expected an XMLHttpRequest')
        in_data = json.loads(request.body)
        bound_contact_form = CheckoutForm(data={'subject': in_data.get('subject')})
        # now validate ‘bound_contact_form’ and use it as in normal Django

در مثال بالا csrf_exempt رو زدیم ها ولی بکار نبریدش کلا یعنی همیشه از امنیتش استفاده کنید

Prefixing the form fields

The problem with this implementation, is that one must remember to access each form field three times. Once in the declaration of the form, once in the Ajax handler of the AngularJS controller, and once in the post handler of the view. This make maintenance hard and is a violation of the DRY principle. Therefore it makes sense to add a prefix to the model names. One possibility would be to add the argument scope_prefix on each form’s instantiation, ie.:

متن بالا رو نمی تونم ترجمه کنم خدتون بخونید بهتره

حالا برای اینکه مشکل متن بالا پیش نیاد بهتره از prefixاستفاده کنیم

class ContactForm(NgModelFormMixin, forms.Form):
    # declare form fields

    def __init__(self, *args, **kwargs):
        kwargs.update(scope_prefix='my_prefix')
        super(ContactForm, self).__init__(*args, **kwargs)

حالا خروجی تو آنگولار به شکل زیر میشه میشه :

<input id="id_subject" type="text" name="subject" ng-model="my_prefix.subject" />

این بالاییه حالا میتونه ارسال آزاکسی رو راحتتر کنه برای اینکه هر ارسال بروی یک آبجکت جاوا اسکریپتی انجام میشه :)) و میشه اون رو بصورت  scope.my_prefix ارسال نمود

$http.post('/url/of/contact_form_view', $scope.my_prefix)

Validate Django forms using AngularJS

NgFormValidationMixin

from django import forms
from django.utils import six
from djangular.forms import NgDeclarativeFieldsMetaclass, NgFormValidationMixin

class MyValidatedForm(six.with_metaclass(NgDeclarativeFieldsMetaclass, NgFormValidationMixin, forms.Form)):
    form_name = 'my_valid_form'
    surname = forms.CharField(label='Surname', min_length=3, max_length=20)
    age = forms.DecimalField(min_value=18, max_value=99)

باز نویسی کنیم به روش ساده تری :

from djangular.forms import NgFormValidationMixin, NgForm

class MyValidatedForm(NgFormValidationMixin, NgForm):
    # members as above
from djangular.forms import NgFormValidationMixin, NgModelForm

class MyValidatedForm(NgFormValidationMixin, NgModelForm):
    class Meta:
         model = Article

    # fields as usual

هر صفحه ای انگولارجی اس نیاز به یک نام منحصربفرد داره در غیر اینصورت اعتبار سنجی ها شاسکول میشن. در نتیجه باید هر فرم از NgFormValidationMixin گرفته بشه

اگر در یک صفحه فقط یک فرم داشته باشیم، نام فرم میتواند در به class declaration مثل مثال پایین اضافه بشه :

تک فرمی :

def get_context_data(self, **kwargs):
    context = super(MyRenderingView, self).get_context_data(**kwargs)
    context.update(form=MyValidatedForm())
    return context

چند فرمی :

def get_context_data(self, **kwargs):
    context = super(MyRenderingView, self).get_context_data(**kwargs)
    context.update(form1=MyValidatedForm(form_name='my_valid_form1'),
                   form2=MyValidatedForm(form_name='my_valid_form2'))
    return context

 Render this form in a template

<form name="{{ form.form_name }}" novalidate>
  {{ form }}
  <input type="submit" value="Submit" />
</form>

Use the directive novalidate to disable the browser’s native form validation

این هم برای دکمه ی سابمیت :

<input type="submit" class="btn" ng-disabled="{{ form.form_name }}.$invalid" value="Submit">

 More granular output

from django import forms
from djangular.forms import NgFormValidationMixin

class MyValidatedForm(NgFormValidationMixin, forms.Form):
    email = forms.EmailField(label='Email')
<ul class="djng-form-errors" ng-hide="subscribe_form.email.$pristine">
  <li ng-show="subscribe_form.email.$error.required" class="ng-hide">This field is required.</li>
  <li ng-show="subscribe_form.email.$error.email" class="">Enter a valid email address.</li>
</ul>

 Combine NgFormValidationMixin with NgModelFormMixin

from django import forms
from djangular.forms import NgFormValidationMixin, NgModelFormMixin

class MyValidatedForm(NgModelFormMixin, NgFormValidationMixin, forms.Form):
    # custom form fields

but don’t do this

class MyValidatedForm(NgFormValidationMixin, NgModelFormMixin, forms.Form):
    # custom form fields

and this :

form = MyValidatedForm(form_name='my_form', scope_prefix='my_model')

css class for errors :

ul.djng-form-errors {
        margin-left: 0;
        display: inline-block;
        list-style-type: none;
}
ul.djng-form-errors li.invalid {
        color: #e9322d;
}
ul.djng-form-errors li.invalid:before {
        content: "\2716\20";  /* adds a red cross before the error message */
}
ul.djng-form-errors li.valid:before {
        color: #00c900;
        content: "\2714";  /* adds a green tick */
}

If you desire an alternative CSS class or an alternative way of rendering the list of errors, then initialize the form instance with

class MyErrorList(list):
    # rendering methods go here

# during form instantiation
my_form = MyForm(error_class=MyErrorList)

توجه کنید و مثال های دیگر

from django import forms

class MyForm(forms.Form):
    # other fields
    date = forms.DateField(label='Date',
        widget=forms.widgets.DateInput(attrs={'validate-date': '^(\d{4})-(\d{1,2})-(\d{1,2})$'}))
<input name="date" ng-model="my_form_data.birth_date" type="text" validate-date="^(\d{4})-(\d{1,2})-(\d{1,2})$" />
angular.module('MyApp', ['ng.django.forms']);

Django REST framework

django REST framework logoDjango REST framework یک فریم ورک قدرتمند و انعطاف پذیر است که طراحی سرور ساید و تا قسمتی کلاینت ساید یک وب پرتال پیچیده را ساده می نماید.تعدادی از دلایلی که شما را مجاب می کند تا از این فریم ورک استفاده نمایید بشرح زیر است :* API های این فریم ورک توسط مرورگر شما قابل استفاده است و نیازی به کد زدن شما ندارد !!* سیستم های کنترل دسترسی شامل پکیج های OAuth1a and OAuth2* سریال سازی شامل ORM and non-ORM data sources* بهینه سازی تمام مسیرهای طراحان دیجانگو در جهت مختصر نویسی و استحکام* مستند سازی قدرتمند و کامل* استفاده توسط تعداد زیادی از شرکت های بزرگ مثل Mozzila and Eventbrite 

نحوه ی نصب :

Requirements

REST framework requires the following:

  • Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)
  • Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7+, 1.8)

The following packages are optional:

Installation

Install using pip, including any optional packages you want…

pip install djangorestframework
pip install markdown       # Markdown support for the browsable API.
pip install django-filter  # Filtering support

…or clone the project from github.

git clone git@github.com:tomchristie/django-rest-framework.git

Add 'rest_framework' to your INSTALLED_APPS setting.

INSTALLED_APPS = (
    ...
    'rest_framework',
)

If you’re intending to use the browsable API you’ll probably also want to add REST framework’s login and logout views. Add the following to your root urls.py file.

urlpatterns = [
    ...
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

خوب با نحوه ی نصب این فریم ورک آشنا شدیمهمانطور که مشاهده می کنید این فریم ورک جایگزین خوبی را برای صفحه مدیریت جانگو ایجاد میکنه. یعنی اگر قبلا از localhost:8000/admin استفاده میشد برای ایجاد کاربری جدید حالا این فریم ورک از همین آدرس و با استفاده از روش دیگری برای ساختن کاربری جدید جایگزین می نمایدمثالی مختصری از نحوه ی استفاده این فریم ورک را اشاره می کنمدر نظر داشته باشید می خواهیم 
TopTal

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

Django Rest framework, Routers

امروز تصمیم گرفتم درباره ی امکانات فوق العاده ای که DRF django rest framework درباره ی مسیریاب ها در اختیار قرار میده مقاله ای برگرفته ازخود سایت این فریم ورک بنویسمهمونطور که می دونید طراحی url ها و روتر ها و همچنین زیبایی اونها چند سالی هست بسیار مطرح شده و فریم ورک های مختلف نیز روش های گوناگونی را برای حل این مسئله ارائه کرده اند. تو این مسئله روبی گویا پیش تازه هست ! :)بعضی از فریم ورک ها مثل روبی امکاناتی را برای شناسایی خودکار url و map کردن با درخواست های ارسال شده بسمت سرور و اتصال آنها به عملیات های سروری فراهم کرده اند. که Django Viewsets نیز هم برای این عملیات ها روش های مختلفی را پیشنهاد نموده است.در DRF شما می توانید بصورت زیر روترهای ساده ای را پیاده سازی نموده و خود DRF انها را به viewset های مشخص شده می رساند و بصورت خودکار CRUD و سایر عملیات ها مثل findBy, findAll و .. را انجام میدهد و البته شما معمولا برای کاستوم کردن آنها ، اقدام به override کردن آنها می نمایید.

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = router.urls

Virtualenv ( برای کاربران ویندوزی )

Virtual Environment به راحتی یک محیط ایزوله شده پایتون رو در اختیارتون قرار میده که تا دیگه نگرانی از تغییر یا تاثیر پروژه جاریتون روی پروژه های دیگه نداشته باشید


مثلا شما می تونید بروی دی جانگو 1.6 کار کنید در صورتی که بقیه ی پروژه هاتون با دی جانگو 1 در دست طراحی هستن.
نحوه ی نصب :
با مراجعه به آدرس زیر فایل مورد نظر را دانلود نمایید:
این پکیج برای دوستانی هست که پایتون 2.7 استفاده می کنن ، سایر دوستان نیز می تونن از آخرین نسخه استفاده کنن
https://pypi.python.org/packages/sou…-1.10.1.tar.gz

سپس آنرا نصب نموده

Python.exe Setup.py install

بعد از نصب پکیج مورد نظر ، در همان پوشه ای که دانلود را از حالت فشرده خارج کرده بودید و نصب انجام شده بود ، پوشه build بوجود می آید و سپس وارد آن شده و مجددا وارد پوشه lib شوید
تنها فایل و پوشه موجود در lib را کپی نموده و وارد پوشه ی پروژه ی خود شده و آنها در پوشه ی پروژه خود کپی نمایید
مثلا پوشه ی D:\MyProject را ایجاد کرده اید و همکنون فایل virtualenv.py و پوشه ی virtualenv_support را در این پوشه کپی نمایید
سپس توسط cmd.exe وارد پوشه MyProject شده و دستور زیر را اجرا نمایید

Python.exe virtualenv.py myapp

پس از اجرای این دستور یک سری از فایل های مورد نیاز اجرای برنامه شما بعنوان فایل های اولیه در پوشه برنامه شما از کپی و ایجاد میشود.

برای اجرای پروژه خود با استفاده از این ابزار میبایست این ابزار را بعنوان پایتون پیش فرض سیستم عامل قرار دهید. برای این کار سازندگان این پکیج در پوشه script ایجاد شده در پوشه myapp فایل بنام activate.bat ایجاد نموده اند ، به راحتی با اجرای این فایل پایتون مجازی بعنوان پایتون پیش فرض تلقی شده و با اجرای deactivate.bat این نسخه از پایتون از حالت پیش فرض خارج میشود