non-fast-forward 에러 해결하기

|

개인적인 연습 내용을 정리한 글입니다.
잘못된 내용이 있다면 편하게 댓글 남겨주세요!


문제 상황

  • github에서 저장소 생성 후 저장소 주소를 remote에 입력(git remote add origin https://github…..)
  • 로컬에서도 정상적으로 초기화(git init)
  • git pull 또는 git merge 명령이 동작하지 않음
  • git push origin master시 [rejected] master -> master (non-fast-forward)에러 발생
git push -u origin master  

To github.com:
! [rejected]        master -> master (non-fast-forward)

error: 레퍼런스를 'git@github.com:'에 푸시하는데 실패했습니다
힌트: 현재 브랜치의 끝이 리모트 브랜치보다 뒤에 있으므로 업데이트가
힌트: 거부되었습니다. 푸시하기 전에 ('git pull ...' 등 명령으로) 리모트
힌트: 변경 사항을 포함하십시오.
힌트: 자세한 정보는 'git push --help'"Note about fast-forwards' 부분을
힌트: 참고하십시오.

원인

깃헙에 생성된 원격 저장소와 로컬에 생성된 저장소 간 공통분모가 없는 상태에서 병합하려는 시도로 인해 발생.
기본적으로 관련 없는 두 저장소를 병합하는 것은 안되도록 설정되어 있음.

해결방법

아래와 같이 git pull 시에 –allow-unrelated-histories 옵션 추가하여 관련 없었던 두 저장소를 병합하도록 허용

git pull origin master --allow-unrelated-histories

pycharm 글자가 안써지는 경우 (IdeaVim 해제)

|

개인적인 연습 내용을 정리한 글입니다.
더 좋은 방법이 있거나, 잘못된 부분이 있으면 편하게 의견 주세요. :)


맥북 초기화를 한 다음 파이참을 재 설치하고나니 갑자기 파이참에 글자가 써지질 않는다.

  • 경로: Preferences > Plugins > IdeaVim 체크 옵션 해제
pycharm_preferences

체크 박스 해제 후 하단의 apply 또는 OK버튼을 눌러주면 되며,

이후 파이참을 재시작하겠냐는 메시지와 함께 재시작하면 적용되어 사용가능하다.

ideavim 해제를 하지않고 사용할 경우 a를 누르면 글자 입력이 가능하다.

pull request 사용하는 방법

|

개인적인 연습 내용을 정리한 글입니다.
더 좋은 방법이 있거나, 잘못된 부분이 있으면 편하게 의견 주세요. :)


오랜만에 pull request를 사용하려고 하니, 헷갈리는 부분이 많아 정리하게 되었다.

우리가 보통 git을 통해 협업을 하다보면 각기 다른 branch를 나누어 이슈를 진행하고 이슈에 대한 테스트가 끝나고 나면 master에 올리기 전 다른 팀원들에게 최종 확인을 받듯이 pull request를 사용할 때가 존재한다. (사실 이전까지의 협업에서 pull request를 사용하지 않다보니 그새 사용하는 방법을 까먹었다..)

해당 미션을 수행해보자.

가정, 협업을 하는 과정에서 하나의 이슈가 발생해 git branch dev1이라는 branch에서 이슈를 진행한다고 가정한다.

git branch dev1

# 해당하는 이슈를 진행한 뒤
git add -A
git commit -m 'issue complete'

git push origin dev1

이렇게 함으로써 master에 push를 올리는 것이 아닌 dev1에 push를 올린다.

이후 해당 github의 저장소를 들어가게 되면

git pull request를 하는 방법

이렇게 등장하는 것을 볼 수 있고 해당 버튼을 클릭하면

git pull request를 하는 방법

해당 이슈를 올리고 상대의 요청 응답을 기다리면 된다.

git pull request를 하는 방법

이럴때 상대가 직접 merge pull request를 해줄수 있다(내가 바꾼 코드에 이상이 없다면) 그러나 반대로 문제가 있을 경우 직접 고쳐줄 수도 있고 이에 대한 코멘트를 달아줄수도, 거절을 할 수도 있다.

반대로 내가 이 github에서 바로 conflict를 해결할 수도 있고 내가 직접 merge pull request를 할 수도 있다.

이렇게 하면 pull request를 하는 방법은 간단하다!

패스트캠퍼스 메모정리(serializer, 배포)

|

패스트캠퍼스 수업을 들으며 정리두었던 메모를 한 곳에 모아둔 곳입니다.


serializer

웹 API를 만들려면 우선 Snippet 클래스의 인스턴스를 json 같은 형태로 직렬화(serializing)하거나 반직렬화(deserializing)할 수 있어야 합니다.

Django REST 프레임워크에서는 Django 폼과 비슷한 방식으로 시리얼라이저를 작성합니다.

ModelSerializer 클래스가 마법을 부리는 도구는 아닙니다. 그저 시리얼라이저 클래스의 단축 버전일 뿐이죠.

필드를 자동으로 인식한다 create() 메서드와 update() 메서드가 이미 구현되어 있다.

In [8]: snippet = Snippet(code='foo = "bar"\n')

In [9]: snippet.save()

In [10]: snippet = Snippet(code='print "hello"\n')

In [11]: snippet.save()

In [12]: serializer = SnippetSerializer(snippet)

In [14]: serializer.data
Out[14]: {'pk': 2, 'title': '', 'code': 'print "hello"\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

In [18]: pprint(serializer.data)
{'code': 'print "hello"\n',
'language': 'python',
'linenos': False,
'pk': 2,
'style': 'friendly',
'title': ''}

In [19]: pprint(snippet)
<Snippet: Snippet object (2)>

In [20]: pprint(dir(snippet))
['DoesNotExist',
'MultipleObjectsReturned',
'__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',

In [21]: content = JSONRenderer().render(serializer.data)

In [22]: content
Out[22]: b'{"pk":2,"title":"","code":"print \\"hello\\"\\n","linenos":false,"language":"python","style":"friendly"}'

In [23]: serializer.data
Out[23]: {'pk': 2, 'title': '', 'code': 'print "hello"\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

In [25]: from django.utils.six import BytesIO

In [26]: stream = BytesIO(content)

In [27]: data = JSONParser().parse(stream)

In [28]: data
Out[28]:
{'pk': 2,
'title': '',
'code': 'print "hello"\n',
'linenos': False,
'language': 'python',
'style': 'friendly'}

In [29]: serializer.data
Out[29]: {'pk': 2, 'title': '', 'code': 'print "hello"\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

In [30]: type(data)
Out[30]: dict

In [31]: type(serializer.data)
Out[31]: rest_framework.utils.serializer_helpers.ReturnDict



In [32]: serializer.data
Out[32]: {'pk': 2, 'title': '', 'code': 'print "hello"\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

In [33]: snippet2 = Snippet(**serializer.data)



In [9]: type(serializer)
Out[9]: snippets.serializers.SnippetSerializer

In [10]: from django.utils.six import BytesIO

In [11]: stream = BytesIO(content)

In [12]: data = JSONParser().parse(stream)

In [13]: serializer = SnippetSerializer(data=data)

In [14]: serializer.is_valid()
Out[14]: True

In [15]: serializer.validated_data
Out[15]:
OrderedDict([('title', ''),
('code', 'print "hello"'),
('linenos', False),
('language', 'python'),
('style', 'friendly')])

In [16]: data
Out[16]:
{'pk': 2,
'title': '',
'code': 'print "hello"\n',
'linenos': False,
'language': 'python',
'style': 'friendly'}

In [17]: serializer.save()
Out[17]: <Snippet: Snippet object (3)>

In [18]: Snippet.objects.create(**serializer.validated_data)
Out[18]: <Snippet: Snippet object (4)>

get_object_or_404

Obj = get_object_or_404(Snippet.objects.all(), pk=)

Try:
	Snippet.objects.create(pk)
	return obj
Except DoesNotExist:
	return Http 404

container_commands & files

container_commands

무조건 배포 이전에 작동, leader_only옵션 존재

-> leader에만 "특정파일"을 생성

files에 넣은 스크립트

배포 이후에 작동하도록 할 수 있음, leader_only옵션이 없음

-> 작동시에 "특정파일"이 있을 경우에만 작동

Nginx, uWSGI

Web Server (Nginx) - HTTP요청 수신 / 응답 송신 (프로토콜: HTTP) - 동적인 처리가 필요하면 Django로 넘겨야 하므로 WSGI사용

WSGI (uWSGI) - Python application과 WebServer간의 인터페이스 (프로토콜: Unix socket)

Python application (Django) - 특정 HTTP요청에 대한 동적응답 생성

EC2를 사용한 배포

Route53 -> Domain, SSL인증서
Load Balancer <- HTTP Request
	Auto-Scaling
		EC2 (Docker -> Docker container)
		EC2 (Docker -> Docker container)		
						RDS
						S3

- ECS
Load Balancer
	Auto-Scaling
		Docker

- EB(ElasticBeanstalk)
Docker

Nginx를 통한 서버관리

Browser
-> (HTTP) Docker
-> (HTTP[forward]) -> Nginx
-> (Nginx conf) -> (UNIX Socket) -> uWSGI
-> (uwsgi.ini) -> (WSGI module) -> Django

Nginx로 서버관리
운영 가능한 사이트 -> A, B, C, D, E (site available)
			링 		크
실제 운영할 사이트 -> A, B, C,   E (site-enabled)

DEFAULT_FILE_STORAGE & STATIC_FILES_STORAGE

DEFAULT_FILE_STORAGE
	일반적인 파일 작업에 쓰이는 Storage backened
	-> 유저가 업로드한 파일은 S3에 저장

STATIC_FILES_STORAGE(FileSystemStorage상속)
	collectstatic에 쓰이는 Storage backend
	-> 프로젝트에 포함된 정적파일은 해당 서버에서 바로 제공

file storage backend

File storage backend
	- Django File
		1 FileField, ImageField를 통해
		2 자신에게 정의된 Storage backend를 이용해서
		3 파일을 기록/삭제/읽음 등등의 작업을 함

	- FileSystemStorage
		하는일 : Django가 file을 다룰 때, 해당 File이 FileSystem의 File일 때의 인터페이스
		-> Django File <--> Python File

	- DropboxStorage (Custom)
		Django가 File을 다룰때, 해당 File이 Dropbox내의 File일 때의 인터페이스

	- S3Storage
		Django ... S3의 File일때


-> 실제로 어떻게 Django에서 파일을 다루면 곧바로 S3에 적용이 되는가?

1 Django에서 CustomBackend를 지정, 이 Backend는 S3와의 통신을 증계한다.
2 S3Backend는 S3가 제공하는 API를 사용해서 Django의 File이 제공하는 메서드들을 자동으로
Request/response처리 -> open(), write(), read()와 같은 메서드들을 지원

Ex) read('파일명')을 실행할 경우
	- Custom backend에서 S3에 연결하기 위한 AWS credentials을 검사
	- S3에 read할 권한이 있다면, boto3를 사용해서 session/client세팅
	- boto3인스턴스를 사용해서 S3가 제공하는 API의 get_file과 같은 기능 실행
	- 실행 결과 데이터를 다시 Django가 사용가능한 File object형태로 파싱
	- Django는 단순히 파일을 불러오 것처럼 편하게 사용

Django에 Django-storage를 깔고(우리가 해야하는 것)
이 안에 (boto3와 AWS)의 연결은 자동으로 이루어 진다.
------

File object: file system 혹은 memory를 사용한다는 전제조건에 있어 이 둘 중 하나에 액세스 할 수 있다.

------

- Python File(FileSystem of Memory상의 File object)
- Django File은 파일에 액세스 할 수 있도록 도와주는 프록시 객체
프록시 : 거쳐간다, 전달해주는, 대리사용 이라는 뜻을 가짐

프록시 객체 : 간접적으로 접속할 수 있도록 해주는 응용프로그램으로 실제 파일에 접근할 수 있도록 도와주는 것
Django는 실제파일이 아님에도 불구하고 이 객체에 접근할 수 있도록 도와주는 것
-> 내가 가지고 있는 backend storage를 통해서 접근할 수 있도록 함

filesystem

name = user/gob.png

for path in settings.STATICFILES_DIRS:
	if os.path.exists(os.path.join(path, name)):
		return True
return False

패스트캠퍼스 메모정리(jekyll, git clone, error log, django)

|

패스트캠퍼스 수업을 들으며 정리두었던 메모를 한 곳에 모아둔 곳입니다.


프로그램

메모리를 올린다는 것은 데이터를 올린다는 것
-> 제대로 된 데이터를 올리기 위해 자료형을 알아야 한다.

데이터의 종류에 따라 type이 달라지고 이 데이터에 따라 메모리가 달라지는데,
메모리를 최대한 알뜰하게 사용하기 위해, 데이터의 타입에 따라 차지하는 메모리의 양이 다르다.

지킬 사진 올리는 코드

<center>
<figure>
<img src="/~/~/screenshot.png" alt="" width="100%">
<figcaption>~</figcaption>
</figure>
</center>

git clone

git remote remove origin
-> git remote add origin <git clone 주소>

git fetch origin master
git merge origin/master

docker에서 error log 확인하는 경로

Cat /var/log/uwsgi/error.log

세션으로 장바구니 유지하는 방법

참고사이트 MUVA

장고를 통한 페이스북 로그인

  1. 페이스북 로그인 버튼 클릭
  2. 페이스북 페이지로 이동, 사용자가 로그인
  3. application으로 redirect되며, ‘code’값을 GET parameter로 받음
  4. code를 access_token과 교환

     4-1 클라이언트가 access_token을 사용해서 사용자 정보를 받아온 추가 정보를 전부 서버로 전송
     4-2 클라이언트가 access_token만 서버로 전송
    

——–클라이언트———

5-1 받아온 정보들로 application에 회원가입 5-2 access_token으로 유저의 페이스북 정보를 받아옴

이후 페이스북에서 받은 유저정보로 application에 회원가입

-> 서버에서는 Token을 돌려줌(DRF로그인 유지 토큰)

로그인 유지시키기

  1. 서버에서 받아온 Token이 쿠키의 ‘token’키값에 저장되어 있음
  2. 클라이언트가 처음 로드 될때 마다, 해당 키를 사용해 HTTP Header의 인증을 만든 상태로 유저 정보를 받아오는 API 실행
  3. API호출에 성공하면 (token이 유효하면) 전송받은 User정보를 사용해 화면을 랜더링(@@로 로그인중)
  4. API호출에 실패하면 (token이 유효하지 않으면) 로그인 버튼을 보여줌

django migration

Python manage.py showmigration
-> migration을 했던 저장 테이블을 따로 두고 다 저장하고 있음을 볼 수 있다.

Db sqlite에서 django_migrations에 들어가서 보면 나와있다.(해당 테이블)
이 상태에서 python manage.py migrate <특정 어플리케이션 이름>
-> 해당 어플리케이션의 적용되지 않은 migration만 migrate한다.

Python manage.py migrate proxy 0001 을 하면 0001까지만 migrate만 되고 그 이후는 unmigration된다.

** document - making query

django form

Class SighupForm(forms.Form):
	field1
	field2
	field3

Form = SignupForm(request.POST) <- bound form
Request.POST를 하면 딕셔너리로 field에는 해당하는 key가 들어올텐데

form.is_valid()

field의 메서드 (3번 실행됨) -> 필드에 대한 정제
	1 to_python()
	2 validate()
	3 run_validate()
		-> (1,2,3통합)Field.clean()
		-> 3개의 메서드를 정상적으로 통과하면 form에 있는 cleaded_date에
		해당 Feild key, value를 추가
		ex) form.cleaned_date['username'] = <입력한 값>

form의 메서드 -> form 자체에 대한 정제
	1 clean_<field_name>이 해당 메서드가 존재하는 수 만큼
		-> Field의 유형이 아닌, 특정 값에 대한 유효성 검증
		ex) 입력받은 username이 중복되는 User가 있으면 validationerror
		-> 검증에 성공하면 cleaned_data[field_name]의 값을 리턴해줌

	2 clean()
		-> 여러개의 Field값에 대해 유효성 검증이 필요할 때
		ex) password1, password2가 같은지
		-> 검증에 성공하면 cleaned_data dict가 될 객체를 반환

cleaded_data는 is_valid를 통과한 애들만 보여준다. (유효한 데이터)

clean 함수

clean()은 장고가 제공하는 유효성 검사기로 잘못된 입력에 대해 validation error를 일으킨다.