var str = "FRANCE";

var re = new RegExp("[A-z]{2}", "ig");

for(var i=0; i<str.length; i++){
        var substring = str.substr(i, 2);
        console.log("re.test(substring)", substring, re.test(substring));
}


위의 소스를 돌려보면 아래와 같이 모두 true / false 가 번갈아 가면서 나온다.

re.test(substring) FR true
re.test(substring) RA false
re.test(substring) AN true
re.test(substring) NC false
re.test(substring) CE true
re.test(substring) E false

정규식이 두글자의 문자일때 true가 반환되어야 하지만 정상적인 경우에도 false가 나온다.

이는 regExp의 g 옵션때문인데, g는  글러벌 속성으로 마지막으로 통과한 정규표현식의 위치를 기억하고

다음번엔 해당 index부터 시작하게 된다.

위의 경우 첫번쨰  FR을 통과 했으므로 LastIndex = 1이 되고, 다음번 RA를 검사할시 LastIndex가 1이기 때문에 RA에서  A부터 검사하여 false이 리턴된다. 그리고 다시 LastIndex는 0으로 초기화된다.


이렇게 for문 안에서 반복적인 정규표현식을 사용할 경우엔 g옵션을 빼고 사용하거나,

혹은 LastIndex를 지속적으로 0으로 초기화를 해야 한다.

re.lastIndex = 0;


참조 : https://stackoverflow.com/questions/1520800/why-does-a-regexp-with-global-flag-give-wrong-results

'web > javascript' 카테고리의 다른 글

js regexp wrong results?  (0) 2018.05.03
overflow-x 된 DOM에서 마우스 휠로 좌우스크롤 움직이기  (0) 2016.06.29
javascript reduce  (0) 2016.06.10
javascrpt map  (0) 2016.06.09

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret





{
    position: fixed;
    top: 0;
    left: 50%;
    margin-left: 216px;
    overflow: auto;
    height: 100%;
}


position을 fixed로 할 시 반응형일 경우 옆의 개체와 일정한 간격을 유지하기 위해선 약간의 꼼수가 필요하다.

left 50%; 와 

margin-left 값을 해당 태그사이즈 / 2 + 간격사이즈 를 px로 주면 반응형에도 알맞게 떨어진다.




WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret

php 서버 실행

web/PHP 2018.04.30 23:12


1. 일반 실행 


   $php artisan serve 


  내장 PHP 웹 서버를 8000 포트에 구동



2. 포트 지정 

    $php artisan serve --port:8080

   8080 포트로 실행 



3. host 지정 

    $ php artisan serve --host 192.168.0.4 --port 8080

   기본으로 localhost 로 실행하기 때문에 localhost 로 접근하지 않으면 접근 되지 않음. 

   지정한 ip로 실행하면 접근 가능 




WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret

오랜만에 라라벨을 실행시켜 보니 다음과 같은 에러가 난다. 


production.ERROR: exception 'ErrorException' with message 'file_get_contents(.env): failed to open stream: No such file or directory' in /Users/uiandwe/Downloads/profile/vendor/laravel/framework/src/Illuminate/Foundation/Console/KeyGenerateCommand.php:57
Stack trace:


해당 에러는 .env 파일이 없어서 나는 에러이다. (해당 파일에 라라벨 기본 설정 및 암호화 관련이 명시되어 있다. 기본 설정을 못 불러와서 나는 초기화 에러이다. )


1.  $php artisan key:generate




위의 명령어를 실행하고 처리되면 끝나지만 위와 같이 에러가 나면 파일 자체가 없는것이다. 


2. $vi .env


APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString
APP_URL=http://localhost

DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null


해당 파일을 만든후 저장한다. 


3. $php artisan key:generate

     Application key [base64:xadA$G!@$%fgkljasdfnAFSDGATZU9E=] set successfully.


다시 1번의 명령어를 실행하여 키를 생성하면 정상적으로 셋팅이되며 이제 라라벨을 실행할수 있다. 




WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret



$sudo apt-get install python3-pip


$sudo pip3 install jupyter


$jupyter notebook


'os > 리눅스' 카테고리의 다른 글

ubuntu jupyter 설치  (0) 2016.08.26
ubuntu 14.04 install ffmpeg  (0) 2015.06.30
linux sync time utc  (0) 2015.05.07
How do I kill all screens?  (0) 2014.10.21
screen cannot exec ...  (0) 2014.10.06
FTP 550: Permission Denied  (0) 2014.09.04

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret

django middleware

web/Django 2016.08.15 21:36



https://docs.djangoproject.com/ja/1.10/topics/http/middleware/



django에서의 middleware는 모든 request/response의 프로세싱의 훅에 해당합니다. 즉 모든 요청 이벤트를 통과하는 중간 처리과정입니다. 


그렇다면 middleware가 언제 필요한가?! 라고 한다면 


만일 특정 url이 들어왔을 경우에만 처리해야 하는 로직이 있다거나 뷰를 리턴할때마다 무엇인가를 추가하거나 빼거나를 할수도 있습니다. 


즉 특정한 app단에서의 django가 아닌 전체 권한을 가지고 움직일때 쓰이는것이 middleware입니다. ( 윈도우에서의 hooking를 생각하시면 됩니다.)


간단하게 소스로 구현한다면 



testmiddle.py

from django.conf import settings
from django.db import connection
from django.template import Template, Context


class SimpleMiddleware(object):
def __init__(self):
pass
# One-time configuration and initialization.

def process_request(self, request):
return

def process_view(self, request, view_func, view_args, view_kwargs):

print(request, view_args, view_func, view_kwargs)
respose = None
return respose

def process_template_response(self, request, response):
print(request, response)
return response

def process_response(self, request, response):
print(request, response)
return response


파일을 만들어 주고 


settings.py 에서



MIDDLEWARE_CLASSES = [
..................
'post.testMiddle.SimpleMiddleware'
]

MIDDLEWARE_CLASSES = [] 부분에 추가해주면 동작합니다. 쉽죠?!



위의 소스는 간단하게 어떤 함수(훅)이 언제 동작하는지를 간단하게 볼수 있습니다. (django v1.9)


사진출처 : https://docs.djangoproject.com/ja/1.9/topics/http/middleware/#middleware


위의 이미지에서 보는바와 같이 각 요청시에 꼭 통과하는 미들웨어 들이 있고 해당 요청에 따라 작동하는 middleware의 훅이 달라지게 됩니다. 



각 이벤트에 따라 작동하는 훅은 달라지며 특정 요청시에만 훅을 적용하는게 성능상 좋습니다.



좀더 알아보기 위해서 process_response()부분에 다음과 같이 추가합니다.


def process_response(self, request, response):

if connection.queries:
execution_sql_time = sum([float(q['time']) for q in connection.queries])
t = Template(
"""
{{nb_sql}} requet{{nb_sql|pluralize:"e,es"}} en {{execution_sql_time}} second{{execution_sql_time|pluralize:"e,es"}}:
{% for sql in sql_log %}
[{{forloop.counter}}] {{sql.time}}s: {{sql.sql|safe}}
{% endfor %}
""")
print("---------------")
print(t.render(Context({'sql_log':connection.queries,'nb_sql':len(connection.queries),'execution_sql_time':execution_sql_time})))
print("---------------")
print(request, response)
return response

바로 해당 url요청에 실행되는 모든 쿼리와 쿼리 시간을 가져 옵니다. 



정상적으로 잘 가져 오는군요. 이렇듯 django의 전체적인 로직에 관여하고 싶다면 middleware로 구현하면 됩니다. 


단!! 서비스 전체에 걸리는 부하이기 때문에 서비스에 영향이 갈수 있습니다. 


'web > Django' 카테고리의 다른 글

django middleware  (0) 2016.08.15
django-summernote 사용하기  (4) 2016.07.23
get 방식의 글자 256자 제한은 잘못된 상식  (0) 2016.05.24
Django South migration error   (0) 2015.09.30
django ajax post data and view.py  (0) 2014.11.08
uwsgi logger disable option  (0) 2014.10.24

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret

gulp 실행시 watch 패키지쪽이 에러가 난다면 



uiandwe@uiandwe-box:~/path/to/project/folder$ gulp [21:56:37] Using gulpfile ~/path/to/project/folder/gulpfile.js [21:56:37] Starting 'watch'... [21:56:37] 'watch' errored after 28 ms [21:56:37] Error: watch ENOSPC at errnoException (fs.js:1031:11)





$echo fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p


파일시스템에서 체크할수 있는 파일의 최대치가 설정되어 있는데 이를 수정해 주면 작동한다. (이부분은 처음알았다...신기)

'web > gulp' 카테고리의 다른 글

gulp Error: watch ENOSPC  (0) 2016.08.01
gulp command does not work  (0) 2016.07.31
ecma6 javascript 를 위한 gulp babel  (0) 2016.06.08
gulp 특정 파일은 제외  (0) 2016.06.02

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret

ubuntu 에서 node와 gulp를 전역으로 설치 했음에도 


/usr/bin/env 
gulp command does not work

라고 에러가 나온다면 다음을 설정해 주자.



$ sudo ln -s /usr/bin/nodejs /usr/bin/node


ubuntu에서 apt-get 으로 설치시 기본 경로가 /usr/bin/nodejs 로 설정되고 패키지들은 /usr/bin/node 로 읽기 때문에 에러가 나는경우가 있다.




'web > gulp' 카테고리의 다른 글

gulp Error: watch ENOSPC  (0) 2016.08.01
gulp command does not work  (0) 2016.07.31
ecma6 javascript 를 위한 gulp babel  (0) 2016.06.08
gulp 특정 파일은 제외  (0) 2016.06.02

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret

이번 시간에는 rest api 생성시 중요한!!(이라 쓰고 항상 까먹는 부분인..) 참조 url을 만들어보겠습니다.

각 인스턴스마다의 detail url / update url / delete url 를 만들어보겠습니다.




1. post/api/serializers.py에 list 용 시리얼라이져를 따로 만들어줍니다. 

    Meta의 fields 부분을 보면 url이 추가된것을 볼수 있습니다. 


    이때 url은 serializers의 HyperlinkedIdentityField를 씁니다.

    여기서 view_name은 현재 각 urls.py에 쓰였던 name을 써주면 알아서 url을 만들어줍니다. 


   여기서 쓰인 posts-api는 /django-rest-api/urls.py에 쓰인 /api/posts/가 입니다.

   그리고 뒤에 detail 은 /post/api/urls.py 에 있는 /<포스트아이디>/ 가 됩니다. 

   lookup_field 부분은 detail 에 있일 pk부분을 명시해줍니다.


   결국 url 부분은 위의 둘의 url을 알아서 합쳐서 보여줍니다. 


from rest_framework.serializers import ModelSerializer, HyperlinkedIdentityField

class PostListSerializer(ModelSerializer):
url = HyperlinkedIdentityField(
view_name='posts-api:detail',
lookup_field='pk'
)

class Meta:
model = Post
fields = [
'pk',
'user',
'title',
'content',
'created_at',
'url',
]



2. serializer를 새롭게 정의하였으니 post/api/view.py의 PostListAPIView()부분의 시리얼라이져를 위에서 선언한 PostListSerializer()로 변경해 줍니다.


from post.api.serializers import PostSerializer, PostListSerializer


class PostListAPIView(ListAPIView):
serializer_class = PostListSerializer
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['title', 'content']
pagination_class = PostLimitOffsetPagination


3. 이제 /api/posts/화면에서 확인해 보면 리스트에 url부분이 작성되어 리턴된것을 확인 할수 있습니다.




4. post/api/serializers.py 에 update / delete  url을 추가해줍니다.

from rest_framework.serializers import ModelSerializer, HyperlinkedIdentityField

class PostListSerializer(ModelSerializer):
url = HyperlinkedIdentityField(
view_name='posts-api:detail',
lookup_field='pk'
)

delete_url = HyperlinkedIdentityField(
view_name='posts-api:delete',
lookup_field='pk'
)

update_url = HyperlinkedIdentityField(
view_name='posts-api:update',
lookup_field='pk'
)

class Meta:
model = Post
fields = [
'pk',
'user',
'title',
'content',
'created_at',
'url',
'update_url',
'delete_url'
]


5. 다시 /api/posts/로 확인해 보시면 데이터 별로 update/delete url이 추가 된것을 확인 하실수 있습니다.





'web > Django_rest_framework' 카테고리의 다른 글

9. href  (0) 2016.07.30
8 pagination  (0) 2016.07.29
7 search  (0) 2016.07.28
6 저장/수정시 유저 저장  (0) 2016.07.27
5. create  (0) 2016.07.27
4 update delete  (0) 2016.07.25

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret


이번 포스팅은 앞써 post list화면의 페이지 네이션을 적용하겠습니다.


해당 포스팅에서의 소스파일은 아래 링크에서 확인 가능합니다.

https://github.com/uiandwe/django_rest_api/tree/a923a4cc3c7666c46685021c30ae78292abd91eb



1. 먼저 /posts/api/views.py 파일에서 rest_framework.pagination 과 PostListAPIView()함수에 페이지네이션을 사용한다는 선언을 해줘야 합니다. 


pagination_class는 사용자가 지정한 limit 값만큼 해당 데이터갯수를  혹은 offset으로 지정한 해당 페이지를 돌려줍니다.

자세한 내용은 링크 참조!

http://www.django-rest-framework.org/api-guide/pagination/#modifying-the-pagination-style


from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination

class PostListAPIView(ListAPIView):
serializer_class = PostSerializer
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['title', 'content']
pagination_class = LimitOffsetPagination

def get_queryset(self, *args, **kwargs):
queryset_list = Post.objects.all()
query = self.request.GET.get("q")
if query:
queryset_list = queryset_list.filter(
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(user__first_name__icontains=query) |
Q(user__last_name__icontains=query)
).distinct()
return queryset_list


2.  /api/posts/?limit=2 링크로 실행해보면 아래 화면과 같이 2개의 데이터만을 리턴하는것을 확인할수 있습니다. 





3. /api/posts/?limit=2&offset=2






3. 이번엔 사용자 지정이 아닌 서버내에서 지정하여 작동하게끔 해보겠습니다.


    post/api/pagination.py 파일 생성 후 아래의 소스를 넣어줍니다.

    

   아래의 default_limit의 경우는 특별히 지정되지 않는다면 2개씩 페이지네이션 결과값을 줍니다.

  max_limit의 경우는 사용자가 limit 값으로 지정시의 최대 값으로 사용자가 10 이상을 요청해도 최대 10개씩 돌려줌 입니다.

from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination


class PostLimitOffsetPagination(LimitOffsetPagination):
max_limit = 10
default_limit = 2




4. 위에서 만든 파일을 참조 및 pagination_class에 넣어줍니다.


from post.api.pagination import PostLimitOffsetPagination

class PostListAPIView(ListAPIView):
serializer_class = PostSerializer
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['title', 'content']
pagination_class = PostLimitOffsetPagination

def get_queryset(self, *args, **kwargs):
queryset_list = Post.objects.all()
query = self.request.GET.get("q")
if query:
queryset_list = queryset_list.filter(
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(user__first_name__icontains=query) |
Q(user__last_name__icontains=query)
).distinct()
return queryset_list


5. 다시 /api/posts/를 확인 하면 아까와 같이 2개씩 페이지네이션이 작동하는것을 볼 수 있습니다.


'web > Django_rest_framework' 카테고리의 다른 글

9. href  (0) 2016.07.30
8 pagination  (0) 2016.07.29
7 search  (0) 2016.07.28
6 저장/수정시 유저 저장  (0) 2016.07.27
5. create  (0) 2016.07.27
4 update delete  (0) 2016.07.25

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret