db의 변화 값을 적용하기 위해 models.py를 변경 후 다음 명령어를 수행하라고 되어

 
권준상

db의 변화 값을 적용하기 위해 models.py를 변경 후 다음 명령어를 수행하라고 되어 있습니다.
python manage.py makemigrations
python manage.py migrate

여기서 makemigrations옵션이 변화에 대한 migrations를 생성한다고 되어 있는데 이게 어떤 내용인가요?
migrate는 변화에 대해 commit인걸로 이해하고 있습니다.

답변 감사합니다

  • Suchan An

    {app_name}/migrations/*.py 내용을 살펴보시면 models.py 에 의한 변경사항이 기록되어 있습니다. 말씀하신 것 처럼 migrate는 변화에 대한 ( 새롭게 생성된 migrations files 에 대한 commit 이 맞습니다. )

    https://docs.djangoproject.com/en/1.9/ref/django-admin/#django-admin-makemigrations

    공대영

    models.py 를 수정하고 makemigrations 를 하면 migrations 폴더인가 거기에 새로운 파일이 생깁니다. 그파일이 alter 된 SQL 문입니다. 파일이 생성될때 변경된 내용이 CMD로 보일거에요. 그걸 migrate 하면 최신걸 마이그레이션 하게 되는거죠

    권준상

    아 책에서 보면 models.py와 py파일의 내용을 같이 맞춰 주어야 한다고 되어 있었는데 해당 내용을 자동으로 생성해 주는 명령어 라고 보면 되겠군요 ^^ 감사합니다

    Chinseok Lee

    makemigrations 명령은 마이그레이션을 위한 생성이라고 보시면 됩니다. django 에서 자동(?)으로 만들어주는 것인데, 이것이 개발자의 의도가 100% 전해지기는 어렵습니다. 개발자의 의도는 특정 필드의 이름을 rename 이었는데, makemigrations 에서는 drop field / create field 가 될 수도 있습니다. 항시 초안 개념으로 보시고, 해당 마이그레이션 파일을 확인하는 습관이 필요합니다. (db는 소중하니깐요. 혹시나 잘못해서 데이터를 날려서는 안 되겠지요.)

    확인 후에, 해당 마이그레이션 파일을 migrate 명령으로 적용하시면 됩니다. 🙂

Advertisements

PHP로 짠 웹 애플리케이션이 있습니다. 주요 내용은 사용자가 웹 브라우저 상에서 특정 값

 
Jeongbae Oh

PHP로 짠 웹 애플리케이션이 있습니다. 주요 내용은 사용자가 웹 브라우저 상에서 특정 값을 입력하면, 이 값을 인자로 하여 외부 API로 콜을 날려서 값을 받아오고, 이 값을 처리해서 DB에 저장한 후, 테이블로 브라우저에 출력해주는 정도입니다.

이 정도의 웹 애플리케이션을 PHP를 전혀 모르고 파이썬+장고도 초보적인 수준으로 아는 사람이 파이썬+장고로 옮기는 것이 가능할까요? 즉 현재 PHP 문법을 전혀 모르는 상태로 PHP 코드를 읽고, 이와 동일하게 동작하는 애플리케이션을 파이썬+장고로 새로 짜는 것입니다. PHP와 파이썬/장고 개발 경험이 있으신 분들의 자문을 구합니다!

  • Chinseok Lee

    예. 가능합니다. // 하다가 모르는 건, 찾아가며 익혀가며 해야겠죠.

    Jeongbae Oh

    생각해보니 너무 당연한 질문을 했네요 ㅋㅋ 아무래도 삽질을 많이 하게 될텐데, PHP 레퍼런스 중 초보자가 빠르게 읽고 기능 파악하는데 있어 잘 정리된 자료가 있을까요? 아무래도 정석을 익히기 보다는 빠르게 참조할 수 있는 리소스가 제일 좋을 것 같아서요…

    Chinseok Lee

    코드를 그대로 포팅하기보다, 각 플랫폼 별로 권장하는 개발방식이 있습니다.

    Django 에도 Django-Way 가 있습니다. 말씀하신 요구사항에서는 Django 의 Form과 ModelForm 을 적극적으로 활용해서 개발하실 수 있겠습니다.

    임대림

    제가 보기엔 Django 로 모두 바꾸시면 기존에 있던 프로그램이 엉키는 문제가 생깁니다. 그냥 필요한 부분만 Django rest api 만드신후 지금 사용하시는 php 프로그램에서 호출하세요.
    정확히 기존에 php 프로그램으로 구현 되어 있는 부분을 모르시고 전부 Django 로 프로그램을 새로 개발 하시다가 문제 생기면 사장님께 혼날 겁니다. ㅋㅋ
    사장 입장에서는 어떤 걸로 만드는지가 중요 하지 않습니다. 빠른 시간에게 결과 물이 나오냐 마느냐가 중요 합니다.

    Dongmin Kim

    Django 는 셋팅도 쉽지 않으실텐데요.

    Jeongbae Oh

    사실 저는 개발자가 아닌 상황에서(^^;;), 제 생각에 복잡도가 그리 높지 않은 백오피스 웹애플리케이션인지라, 개발자 도움 없이 저의 필요에 따라 커스터마이즈 해나가면 업무에 활용하기 편하지 않을까 해서 망상 중이었습니다. 아무쪼록 모두들 조언해주셔서 감사합니다! 😃

django-allauth 에 kakao provider 를 구현해서 붙여봤는데, 생각보다

 
Chinseok Lee

django-allauth 에 kakao provider 를 구현해서 붙여봤는데, 생각보다 심플하게 붙였네요.

다만 kakao rest-api 에서는 client_secret 가 없는 데, django-allauth oauth2 에서는 인자로 지정하기 때문에, client_secret 를 뺄려고 get_access_token 함수를 재정의 해줬습니다. // client_secret 를 넘기면 인증오류가 뜹니다.

정리해서 공개해봐야겠습니다. // AskDjango

  • Jihoon Kong

    미리 감사합니다.

    우준식

    기대합니다 ㅋㅋ

    Chinseok Lee

    naver 도 붙여놨습니다. 정리 중이예요. 🙂

특정 페이지에서만 로그아웃이 된 상태가 되는데, 어떤 문제 때문에 발생하는지 원인을 모르겠

 
Donghyun Seo

특정 페이지에서만 로그아웃이 된 상태가 되는데, 어떤 문제 때문에 발생하는지 원인을 모르겠네요.

다른 페이지들과 동일하게 render를 사용하는데 이 페이지만 로그아웃된 상태가 되네요. 그러다가도 다른 페이지로 이동하면 해당 페이지는 로그인이 된 상태가 되네요.

  • Chinseok Lee

    같은 hostname 이라면, 동일하게 render 가 안 된 듯 합니다. 응답 만드는 코드를 확인해보세요.

    Donghyun Seo

    이진석 다른 곳과 동일하게 아래 코드로 render하였는데, 이 페이지만 문제가 생기네요.

    def user(request, user_id):
    “””
    Display a user

    :param request: request
    :param user_id: user id
    :return: render
    “””
    _user = get_object_or_404(User, id=user_id)
    _groups = _user.groups

    return render(
    request,
    ‘archive/user/user.html’,
    {
    ‘user’: _user,
    ‘groups’: _groups,
    }
    )

    서로 다른 template 폴더에 있으면 authentication을 전달하지 못하나요?

    Chinseok Lee

    아니요. 템플릿과는 상관없습니다.

    django template 내에서는 “user” 를 통해, 현재 로그인된 user 객체에 접근할 수 있는 데요. user_id 로 찾은 _user 를 “user” 로서 넘겨줬기 때문에, 변수 overwrite 가 된 듯 하네요.

    render 에 인자로 넘겨주는 “user” 를 다른 이름으로 변경해서, 테스트해보세요. // AskDjango

    Donghyun Seo

    이진석 감사합니다. 해당 문제였네요. django user와 따로 수집한 user를 같이 사용하다보니 이런 문제가 자주 발생하네요.:(

게시물에 저자를 저장할때 보통 views.py에서 article = form.save(

 
Woo-cheol Jeong

게시물에 저자를 저장할때 보통 views.py에서

article = form.save(commit=False)
article.author = request.user
article.save()

와 같은 방식으로 해왔는데, author 뿐만 아니라 몇몇 ManyToMany relation 설정이 추가되다 보니 view가 점점 길어지는게 마음에 들지 않아 author와 달리 request와 무관하게 설정할 수 있는 관계는 form 클래스 save 메쏘드에서 설정하도록 save 메쏘드를 오버라이드 하고 싶습니다.(말이 복잡하네요…)

현재 form 클래스 save 메쏘드에서 commit 인자를 이용할 수 있도록 오버라이드 하고 싶어 이런 식의 방법을 구상중입니다.

def save(self, commit=False):
..(향후 commit=True로 save시 호출될 save_m2m에서 처리할 수 있도록 관계 설정)..
return super(FORM, self).save(commit)

문제는… 제 짧은 지식으로는 save_m2m에서 처리할 수 있도록 하려면 관계를 어떻게 설정해둬야 하는지 도무지 모르겠습니다… 어떻게 좋은 방법이 없을까요..?

  • Woo-cheol Jeong

    ㅜㅜ

    박영록

    https://docs.djangoproject.com/en/1.9/ref/forms/fields/#django.forms.ModelMultipleChoiceField 이건 쓰고 있으신가요?

    Woo-cheol Jeong

    현재 Tag모델과 Article 모델을 ManyToManyField로 엮어두었고, Article의 form에서 Tag 입력은 forms.CharField를 통해 복수 태그를 쉼표로 구분하여 입력받습니다. 그 후 form 내의 clean_tags 메쏘드에서 쉼표로 구분된 복수 태그를 추출하여 tag_list를 반환하도록 하였고, views.py에서 Article save 후 cleaned_data[‘tags’]를 통해 tag_list를 받아 Article 모델에 정의해둔 save_tag 메쏘드를 호출하여 Tag를 저장하고 있습니다.

    Woo-cheol Jeong
    Woo-cheol Jeong
    Woo-cheol Jeong
    Woo-cheol Jeong

    말이 조금 복잡해진 것 같아 소스코드 첨부합니다!

    박영록

    본래 ModelMultipleChoiceField를 쓰면 ManyToManyField를 자동으로 연결시켜주는데, 이미 있는 Tag를 선택해서 연결시키는 것이 아니라 즉석에서 생성해야 할 수도 있기 때문에 자동처리가 안되서 이렇게 하셨나보네요. 이 경우에는 완전히 깔끔한 해결책은 없고, 몇 가지 트릭으로 최적화는 할 수 있을 것 같습니다.

    저라면 write_article에서 먼저 Tag 모델 목록을 만든 다음, 그 id 목록을 request.POST[‘tags’]에 list로 넣고 WriteArticle에 전달한 다음 바로 form.save()를 해버릴 것 같습니다. 물론 WriteArticle의 fields에는 tags도 정의되어 있어야할 거구요.

    혹은 submit할 때 이벤트로 tag만 먼저 submit해서 생성한 다음 form에 tag id들을 채워넣고 최종 submit을 하는 방식도 가능하구요.

    이외에도 여러 가지 방법이 있을 텐데, 여튼 중요한 포인트는 django의 ModelForm이 기본적으로 해주는 일을 최대한 활용하는 방식으로 구현하면 코드 양이 많이 줄어들 거라는 것입니다.

    Woo-cheol Jeong

    오오 친절한 답변 정말 감사합니다! 후자의 방법으로 도전해봐야겠어요. 정말 감사합니다! 🙂

OneToOneField를 이용하여 customUser 모델을 만들었을 때, 추가한 필드를

 
SungYong Lee

OneToOneField를 이용하여 customUser 모델을 만들었을 때, 추가한 필드를 건드리지않았을 때는 customUser로 인식하지 않는 문제에 대한 질문이 있습니다.

https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#extending-user 를 참고해서 아래와 같이 만들었어요.

아바타 이미지를 업로드 하지 않은 사용자들은 기본으로 제공하는 image의 url을 보내주도록 하는게 목표였습니다.

—————-some_app.views.py————–
class CustomUser(models.Model):
….user = models.OneToOneField(User, related_name=’profile’)
….avatar_img_file = models.ImageField(upload_to=upload_to, blank=True, null=True)

….def get_avatar_url(self):
……..if not self.avatar_img_file:
…………return “http://placeholder.me/40×40”
……..else:
…………return self.avatar_img_file.url

———some_template.html—————
[…생략…]

[…생략…]

그런데, 제대로 작동이 되지 않더군요. 이미지를 한번이라도 업로드 하지 않았던 회원은 아무 url도 가져오지 않고 있었습니다. 원래 목표는 avatar_img_file이 비어 있는 회원들은 디폴트 이미지의 url을 돌려주는 것이었는데, 이미지를 올렸다가 삭제한 경우에는 디폴트이미지 url을 잘 반환시켜주는데 말입니다.

shell에서 CustomUser.objects.count()로 회원 갯수를 세보니, 아바타 이미지를 한번이라도 업로드했던 회원들만 CustomUser에 잡히고 (이미지를 올렸다가 삭제한 경우에도 CustomUser로 잡힙니다.), 나머지는 그냥 User로만 되어 있었습니다. 그래서 get_avatar_url에 접근하지 못했던 것 같아요.

이런 경우에 어떻게 해야하나요?

  • SungYong Lee

    아 참! 메리크리스마스입니다

    김명준

    회원가입을 할 때 새로 생성된 회원의 User pk 값이 들어간 CustomUser 객체가 생성되어야 하는거 아닌가요?(저도 초보라..)그래서 저는 회원가입을 처리하는 뷰에서 객체를 생성하고 디폴트 이미지 url을 지정해줬습니다.

    SungYong Lee

    아 그런가요
    전 admin을 통해서 생성했었습니다.

    Chinseok Lee

    각 User 별로 CustomUser 이 생성이 되어야 합니다. 없다면 user.profile 에서 CustomUser.DoesNotExist 예외가 발생하게 됩니다. 템플릿 내에서는 이 DoesNotExist 예외를 무시하고 별 다른 메세지를 보여주지 않습니다.

    각 User 인스턴스의 post_save 시에 CustomUser 인스턴스를 생성해주시던지, 혹은 따로 CustomUser 인스턴스 유무를 체크해서 생성해주는 함수를 만들어주셔도 좋겠습니다. // AskDjango

    SungYong Lee

    답변 감사합니다. 현재 allauth를 사용하고 있는데, User의 post_save를 건드리려면 allauth에서 회원가입 부분을 건드려야 하려나요…..생각보다 꽤나 복잡하네요…

    Chinseok Lee

    아니요. 쓰시는 코드에서 django.contrib.auth.models.User 모델을 임포트해서 post_save 시그널을 처리하시면 됩니다. // allauth 도 django.contrib.auth.models.User 모델을 쓰고 있으니깐요.

    from django.contrib.auth.models import User
    from django.db.models.signals import post_save

    def user_saved(sender, **kwargs):
    … if kwargs[‘created’]:
    ……. # 관련 처리

    post_save.connect(user_saved, sender=User)

    django 에서는 settings.AUTH_USER_MODEL 을 지정함으로서 User 모델을 변경할 수 있는 데요. 이 경우는 처리가 좀 더 필요합니다.

    SungYong Lee

    이진석 감사합니다. signal이라던지 각 인스턴스 간의 관계라던지 이런 지식들이 전혀 없었는데 덕분에 알게 되었습니다. 말씀해주신 것을 토대로 검색해본결과 좋은 문서가 있어서 그걸 보고 따라하니 원하던 것이 해결되었습니다.

    고맙습니다! 장고 커뮤니티 너무 좋아요.

    다른 분들을 위해서 링크를 공유합니다.
    http://www.marinamele.com/taskbuster-django-tutorial/model-creation-onetoone-relationship-signals-django-admin

안녕하세요! 현재 Django 1.8(+ Django Rest Framework)과 Ang

 
Dae-won Seo

안녕하세요!
현재 Django 1.8(+ Django Rest Framework)과 Angular 1.4를 이용해서 웹서비스를 만들고 있는데, CSRF 문제 때문에 질문 드립니다.

Django와 Angular를 다른 서버에 띄워서 개발하고 있는데요,
로그인을 위해서 Angular에서 Django의 로그인 API를 호출해야 할 때, 쿠키에 CSRF 토큰을 담아서 보내야 합니다.

그런데 Angular 입장에서 토큰을 쿠키에 담아 보내려면, 먼저 장고 서버에 갔다 와야 하는데,
일단은 로그인 하기 전에, 먼저 Django의 로그인 Form 태그가 있는 Template을 호출해서 쿠키를 받아오고 있습니다.
그런데 화면에 그리지도 않을 HTML을(실제 쓰는 로그인 HTML은 Angular가 보내주기 때문에…) 쿠키 하나 때문에 통째로 가져오는게 너무 찝찝한 상황입니다.

고수 분들은 이 경우에 보통 어떤식으로 처리하시는지 궁금합니다.
감사합니다!

  • Youngsoo Jung

    좀 다른 얘기지만, 장고 자체가 풀스택에 가까운 프레임워크라서 앵귤러 등 프론트앤드 프레임워크를 같이 쓰면 중복이 많습니다. 바둑으로 예를들면 빈삼각이 많아진다고 할까요. 고심끝에 저는 장고만 씁니다.

    Enoch Lee

    https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax
    이 곳을 참조하시면 될듯 합니다.

    Ju-won Lee

    app.config([‘$httpProvider’,
    function($httpProvider) {

    // csrf token
    $httpProvider.defaults.xsrfHeaderName = ‘X-CSRFToken’;
    $httpProvider.defaults.xsrfCookieName = ‘csrftoken’;

    // ajax header
    $httpProvider.defaults.headers.common[‘X-Requested-With’] = ‘XMLHttpRequest’;
    }
    ]);

    $httpProvider 객체에 설정을 해 두시면 애플리케이션에서 $http 이용해 보내는 모든 리퀘스트에 토큰이 박힙니다. ㅎㅎ

    Chinseok Lee

    csrf 처리를 할려면, 일단 해당 서버로부터 csrf_token 값을 가져올 수 밖에 없죠.

    그런데 웹페이지에서 일반적인 post 요청이 아니라, api 뷰를 호출하는 것이기 때문에 csrf 를 끌 수도 있을 듯 하네요.

    특정 URL 에 대해 csrf 를 끌려면 미드웨어를 작성해서, CsrfViewMiddleware 전에 해당 URL 패턴에 대해 request.csrf_processing_done = True 설정을 할 수도 있겠습니다.
    https://github.com/django/django/blob/master/django/middleware/csrf.py#L110

    Dae-won Seo

    일단 지금까지 적용한 방법은 rotate_token만 수행하는 get api를 만들고 post 호출 전에 한번 호출하는 방법으로 변경했습니다 ㅎㅎ..

    Sun Wook Kim

    로그인 할때는 Permission을 AllowAny 로 하셔서
    아이디랑 비번이 맞을때 토큰을 보내주면 안되나요?
    왜 로그인 하기도 전에 토큰을 받아와야하나요??