npm verb about to build /home/username/html/node_modules/laravel-elixir/node_modules/partialify
npm info build /home/username/html/node_modules/laravel-elixir/node_modules/partialify
npm verb afterAdd /home/username/.npm/is-glob/2.0.1/package/package.json not in flight; writing
npm verb afterAdd /home/username/.npm/normalize-path/2.0.1/package/package.json not in flight; writing
npm verb readDependencies loading dependencies from /home/username/html/node_modules/laravel-elixir/node_modules/gulp-uglify/node_modules/uglify-js/package.json
npm verb write writing to /home/username/html/node_modules/laravel-elixir/node_modules/gulp-babel/node_modules/through2/node_modules/readable-stream/package.json
Killed


* 대안


서버의 메모리를 늘린다.

또는 Swap을 추가한다.


아래는 1G의 Swap을 추가하는 예이다.


sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo "/swapfile   none    swap    sw    0   0" >> /etc/fstab


Posted by C마노
,

Manager는 Django 모델에 데이터베이스 쿼리작업을 제공하는 인터페이스입니다.

Django 응용프로그램의 모든 모델에는 최소 하나 이상의 Manager가 있습니다.


기본적으로 Django는 모든 Django 모델 클래스에 objects 라는 이름의 Manager를 추가합니다.


그러나, 객체 필드를 이름으로 사용하거나 Manager용 객체 이외의 이름을 사용하려는 경우에는 모델별로 이름을 변경할 수 있습니다.


주어진 클래스에 대해 Manager의 이름을 바꾸려면, 해당 모델에서 models.Manager() 유형을 클래스 속성을 정의하십시오.


from django.db import models

class Person(models.Model):
    #...
    people = models.Manager()


기본 Manager 클래스를 확장하고 모델에서 사용자 정의 Manager를 인스턴스화 하여 특정 모델에서 사용자 정의 Manager를 사용 할 수 있습니다.


사용자 정의 Manager를 사용하는 이유는 2가지가 있습니다.


Manager 메소드를 추가하거나 Manager가 반환하는 초기 QuerySet을 수정하는 이유입니다.


[대표적인 예]


class PostManager(models.Manager):
def active(self, *args, **kwargs):
# Post.objects.all() = super(PostManager, self).all()
return super(PostManager, self).filter(draft=False).filter(publish__lte=timezone.now())


추가 관리자에 메서드 추가하기


우선은 모델에 "테이블 수준"의 기능을 추가하고 싶을 때 사용할 수 있습니다.


행 수준의 기능을 추가할때는 Model 메소드를 사용하십시오 여기서는 컬럼기준일떄 이야기합니다.


사용자 정의 관리자 메소드는 원하는 모든 것을 리턴 할 수 있습니다. QuerySet을 리턴할 필요는 없습니다.


예를 들어, 사용자 정의 관리자는 모든 OpinionPoll 객체의 목록을 반환하는 with_counts() 메서드를 제공합니다.


그런데 각 쿼리에는 집계 쿼리의 결과인 num_responses 속성이 추가로 있습니다.


from django.db import models

class PollManager(models.Manager):
    def with_counts(self):
        from django.db import connection
        with connection.cursor() as cursor:
            cursor.execute("""
                SELECT p.id, p.question, p.poll_date, COUNT(*)
                FROM polls_opinionpoll p, polls_response r
                WHERE p.id = r.poll_id
                GROUP BY p.id, p.question, p.poll_date
                ORDER BY p.poll_date DESC""")
            result_list = []
            for row in cursor.fetchall():
                p = self.model(id=row[0], question=row[1], poll_date=row[2])
                p.num_responses = row[3]
                result_list.append(p)
        return result_list

class OpinionPoll(models.Model):
    question = models.CharField(max_length=200)
    poll_date = models.DateField()
    objects = PollManager()

class Response(models.Model):
    poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE)
    person_name = models.CharField(max_length=50)
    response = models.TextField()


이 예제에서는 OpinionPool.objects.with_counts() 를 사용해서 num_responses 속성을 가지는 OpinionPoll 객체의 목록을 반환합니다.


관리자의 기본 QuerySet은 시스템의 모든 객체를 반환합니다.


예를들어 이런 모델이 있다고 가정합시다.


from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

Book.objects.all() 문은 데이터베이스의 모든 책을 반환합니다.


Manager.get_queryset() 메서드를 재정의 해서 Manager의 기본 QuerySet을 재정의 할 수 있습니다.


get_queryset()은 QuerySet을 반환해야만 합니다.


예를들어 다음 모델에는 두개의 관리자가 있고, 하나는 모든 객체를 반환하고 하나는 Roald Dahl책만 반환합니다.


# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl')

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.

이 샘플 모델을 사용하면 Book.objects.all()은 데이터베이스의 모든책을 반환하지만, Book.dahl_objects.all()은 Roald Dahl이 작성한 책만 반환합니다.


물론 get_queryset()은 QuerySet 객체를 반환하기 때문에 filter(), exclude() 및 기타 모든 QuerySet 메서드를 사용 할 수 있습니다. 


Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()

그리고 하나의 모델에서 여러관리자를 사용 할 수 있다에 주목해주세요


모델에 원하는 만큼의 Manager() 인스턴스를 첨부할 수 있습니다. 이렇게하면 모델에 대한 일반적인 "필터"를 쉽게 정의 할 수 있습니다.


예제입니다.


class AuthorManager(models.Manager):
    def get_queryset(self):
        return super(AuthorManager, self).get_queryset().filter(role='A')

class EditorManager(models.Manager):
    def get_queryset(self):
        return super(EditorManager, self).get_queryset().filter(role='E')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
    people = models.Manager()
    authors = AuthorManager()
    editors = EditorManager()

이 예제에서는 Person.authors.all(), Person.editors.all() 및 Person.people.all()을 요청하여 예측 가능한 결과를 얻을 수 있습니다.




Posted by C마노
,

Restful 공부중. permission에 대해선 확실히 알고 가야 할것같아. 따로 포스팅한다.


[Permission]


Permission 체크는 항상 view 의 시작에 하게 되는데. ( 다른코드의 진행 전에 실행된단 이야기다 )

기본적으로 Permission Check는 request.user 와 reuqest.auth 의 정보를 사용해서 인증을 처리한다.


Permission은 사용자가 정해진 클래스 이외의 클래스의 접근을 거부하거나 허용하는데 사용한다.


가장 간단하게 사용하는 방법은 인증된 사용자에게는 Access를 허용하고 인증되지 않은 모든 사용자는 Access를 거부하는방법이다.


이것은 REST 프레임 워크의 IsAuthenticated  에 해당합니다.


IsAuthenticated  보다 조금 덜 엄격한 스타일은 권한 없는(인증 되지 않은)사용자에게 읽기 전용 액세스를 허용하는 IsAuthenticatedOrReadOnly  가 있겠다.


[어떻게 권한을 결정하나?]


REST Framework의 권한은 항상 권한 클래스의 목록으로 정의되는데,

View의 본문이 실행되기 전에 목록의 각 권한이 검사된다.


만약 권한통과에 실패하게 되면 exceptions.PermissionDenied 나 exceptions.NotAuthenticated 의 Exception이 raise 하게되고, View의 본문은 실행되지 않는다.


권한 검사가 실패하면, 403 Forbidden또는 401 Unauthorized 응답이 반환되게 된다.


* 요청이 성공적으로 인증되었지만, 권한이 거부되었습니다. - 403에러가 리턴된다.

* 요청이 성공적으로 인증되지 않고 헤더가 WWW-Authenticate 헤더를 사용하지 않았다. - 403에러가 리턴된다.

* 요청이 성공적으로 인증되지않고 헤더가  WWW-Authenticate 를 사용했다 - 401에러가 리턴된다.


[객체레벨 권한]


Object-level-permission은 사용자가 특정한 객체에 대한 작업을 허용해야 하는지 (일반적으로 model 인스턴스입니다) 에 대한 결정을 하는데 사용되어 진다. 


객체 레벨 권한은 .get_object()가 호출 될때, REST 프레임워크의 일반 뷰에 의해 실행됩니다.


사용자가 만약 해당 객체에 권한이 없으면 exceptions.PermissionDenied 가 리턴됩니다.


자신의 View를 작성하고 있고, 오브젝트 레벨 권한을 적용하려는 경우나 일반 View에서 get_object를 오버라이드 하는 경우 오브젝트를 검사한 시점에서 뷰에서 .check_object_permissions(request, obj) 를 호출해야 합니다.


[예제]


def get_object(self):
    obj = get_object_or_404(self.get_queryset())
    self.check_object_permissions(self.request, obj)
    return obj

[권한 정책 설정]


기본 권한 정책을 설정할 수 있는데 DEFAULT_PERMISSION_CLASSES 를 사용해서 기본 권한 정책을 사용 할 수 있습니다.


REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

지정하지 않으면 설정은 기본적으로 제한없는 엑세스를 허용합니다.


'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',
)

또한 클래스 기반 APIView 를 사용해서 VIew마다 또는 viewSet마다 인증 정책을 설정할 수 있습니다.


from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)

데코레이터를 사용 할 수도 있습니다.


from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)

[API 레퍼런스]


AllowAny


제한되지 않은 엑세스를 허용합니다.

IsAuthenticated


인증되지 않은 사용자에게 권한을 거부하고 그렇지 않으면 허용합니다.

IsAdminUser


IsAdminUser 권한 클래스는 user.is_staff가 True인 경우를 제외하고 모든 사용자의 권한을 거부합니다.

IsAuthenticatedOrReadOnly


이 권한은 API에서 익명 사용자에게 읽기 권한만 허용하고, 인증된 사용자에게는 쓰기 읽기권한을 허용하려는 경우에 적합합니다.



[커스텀퍼미션]


BasePermission을 상속받고,


  • .has_permission(self, request, view)
  • .has_object_permission(self, request, view, obj)

해당 2가지 함수를 오버라이딩 해야합니다.

요청에 대한 엑세스 권한이 부여되면 메서드는 True를 반환, 그렇지 않으면 False를 반환해야만 합니다.


요청이 읽기 작업인지, 아니면 쓰기 작업인지 알아야 하는경우 SAFE_METHODS 상수와 비교해서 요청방법을 확인해합니다.


if request.method in permissions.SAFE_METHODS:
    # Check permissions for read-only request
else:
    # Check permissions for write request

검사 방법은 has_permission 검사가 통과 되어야지만, has_object_permission이 호출 된다는것을 명심하시기 바랍니다.

테스트가 실패 할 경우 사용자 지정 권한은 PermissionDenied 예외를 발생시킵니다.


예외와 관련된 오류 메세지를 변경하려면 message = '에러메세지' 를 사용하십시오.


from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission):
    message = 'Adding customers not allowed.'

    def has_permission(self, request, view):

[예제]


다음은 들어오는 요청의 IP 주소를 블랙리스트와 대조해서 IP가 블랙리스트에 올랐으면 요청을 거부하는 권한클래스의 예입니다.


from rest_framework import permissions

class BlacklistPermission(permissions.BasePermission):
    """
    Global permission check for blacklisted IPs.
    """

    def has_permission(self, request, view):
        ip_addr = request.META['REMOTE_ADDR']
        blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
        return not blacklisted

들어오는 모든 요청 (POST,GET,PUT...) 에 대해 실행되는 전역 권한 뿐만 아니라 특정 개체 인스턴스에 영향을 주는 작업에 대해서만 실행되는 개체수준 사용권한을 만들 수도 있습니다.


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Instance must have an attribute named `owner`.
        return obj.owner == request.user


Posted by C마노
,