Board project - 3

[ Board project ]

  • F() 객체

    • 모델의 필드 값을 참조하여 데이터베이스 작업을 수행할 수 있다.
      1
      2
      3
      4
      5
      6
      7
      8
      from django.db.models import Q, F
      from board.models import * # Board, Category, Document

      # 'title'이라는 문자열을 검색
      Document.objects.filter(title__icontains='title')

      # 필드 값인 title을 참조하여 검색
      Document.objects.filter(title__icontains=F('title'))
  • selet_related()

    • Join Query를 만들어서 한 큐에 데이터를 불러온다.
    • Join을 사용하기 때문에 ForeignKey와 같이 single valued relationships에서만 사용 가능하다.
  • prefetch_related()
    • 모델 객체들을 불러서 코드 단에서 병합한다.
    • ManyToMany를 포함해서 모든 relationships에서 사용 가능하다.
  • select_related()와 prefetch_related()를 사용하지 않는 경우
    • 참조 테이블에 대한 데이터 질의를 항상 수행한다.
  • QuerySet Cache

    • Query는 마지막까지 지연된다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      from django.db.models import Q, F
      from board.models import *

      # 아래 코드를 실행해도 DB에 쿼리는 수행되지 않는다.
      object_list = Document.objects.all()

      # 아래와 같이 쿼리셋을 순회해야 쿼리가 수행된다.
      for object in object_list:
      print(object.author.username)
    • DB에 레코드들을 실제로 와서 Django model로 변환되는 것을 평가(evaluation)라고 한다.

    • 평가된 모델들은 쿼리셋의 내장 캐시에 저장된다.
    • 따라서 같은 쿼리셋을 재순회하더라도 DB에 전달하지 않는다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      # 여기는 쿼리가 실행되지 않은 부분
      object_list = Document.objects.all()

      # 캐싱이 일어나지 않음
      object_list[4]
      # 캐싱이 일어나지 않음
      object_list[5]


      object_list = Document.objects.all()
      [object.title for object on object_list]

      # 캐싱이 일어남
      object_list[4]
      # 캐싱이 일어남
      object_list[5]

      # 캐싱이 일어나지 않는다.
      # Document.object.all()을 변수에 담아놓고 실행해야 한다.
      for object in Document.object.all():
      print(object.title)
  • exclude()

    • 특정 조건을 제외한 나머지 데이터들을 가져오기 위해 사용한다.
    • 여러 조건들을 묶을 때에는 사용되지 않는다.
  • 정렬

    • QuerySet의 기본 정렬값 = 모델에서 설정값

      1
      2
      3
      Model:
      class Meta:
      orderng = ['field name']
    • 기본 정렬값은 pk

    • 오름차순(asc)

      1
      Document.objects.all().order_by('title')
    • 내림차순(desc)

      1
      Document.objects.all().order_by('-title')
  • 삭제

    1
    Document.objects.get(pk=1).delete()
  • 갱신

    1
    2
    3
    4
    5
    6
    Document.objects.get(pk=1).update(title="example")

    # 전체 레코드에 대한 갱신
    Document.objects.all().update(title="example")

    Document.objects.filter(title__icontain='word').update(title="example")
  • logging 사용하기

    • setting.py에 추가한다.
    • 터미널 창에서 쿼리문 출력을 확인한다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      LOGGING = {
      'version':1,
      'disable_existing_loggers':False,
      'handlers': {
      'console':{
      'class':'logging.StreamHandler',
      }
      },
      'loggers':{
      'django':{
      'handlers':['console'],
      'level':'DEBUG',
      }
      }
      }

      """
      import logging
      l = logging.getLogger('django.db.backends')
      l.setLevel(logging.DEBUG)
      l.addHandler(logging.StreamHandler())
      """
  • 소셜 미디어 로그인 연동하기

    • Django-allauth 사용
      • django-allauth 문서 홈페이지로 이동하여 참고
    • 네이버 이용
    1. 해당 모듈을 설치한다.

      1
      $ pip install django-allauth
    2. settings.py를 수정한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      INSTALLED_APPS = [
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      'board',
      'storages',
      # 항목 추가
      'django.contrib.sites',
      'allauth',
      'allauth.account',
      'allauth.socialaccount',
      # 네이버를 이용하기 위해 추가
      'allauth.socialaccount.providers.naver',
      ]

      # 항목 추가
      AUTHENTICATION_BACKENDS = (
      'django.contrib.auth.backends.ModelBackend',
      'allauth.account.auth_backends.AuthenticationBackend',
      )

      # 추가
      SITE_ID = 1

      # 로그인 후에 이동할 경로 추가
      LOGIN_REDIRECT_URL = '/'
    3. config/urls.py에 경로를 추가한다.

      1
      path('accounts/', include('allauth.urls')),
    4. migrate를 한다.

      1
      $ python manage.py migrate
    5. django-allauth 문서 홈페이지에서 providers 탭에서 네이버 항목으로 이동한다.

      • https://developers.naver.com/appinfo 로 이동한다.
      • 애플리케이션을 등록한다.
        • 애플리케이션 이름을 작성한다.
        • 사용 API는 네아로(네이버 아이디로 로그인)를 선택한다.
        • 필수 항목에 회원이름과 이메일만 체크한다.
          • 나머지는 추가 항목으로 넣을 수 있다.
        • 환경은 PC웹을 선택하고 URL을 다음과 같이 설정한다.
          1
          2
          3
          4
          5
          6
          - 서비스 URL
          >> http://127.0.0.1:8000

          - Callback URL
          - django-allauth 문서 홈페이지에서 providers 탭의 네이버 항목에 있다.
          >> http://127.0.0.1:8000/accounts/naver/login/callback/
    6. 서버를 실행하고 관리자 사이트로 접속하고, 소셜 어플리케이션을 추가한다.

      • 소셜 계정/소셜 어플리케이션/소셜 어플리케이션 추가
        1
        2
        3
        4
        5
        제공자 : Naver
        이름 : 네이버 로그인
        클라이언트 아이디 : 네이버 API 등록 시 발급되는 Client ID
        비밀 키 : 네이버 API 등록 시 발급되는 Client Secret
        sites : example.com 선택
    7. http://127.0.0.1:8000/account/login 에 접속하여 naver를 누르고 로그인한다.

      • admin으로 접속되어 있다면 로그아웃하자.
      • base.html에 로그인/로그아웃 URL을 추가하자.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        <!--// base.html //-->
        {% if user.is_authenticated %}
        <!--//
        django-allauth 문서 홈페이지/Views 탭에서 로그인, 로그아웃 URL 이름 확인
        //-->
        <a href="{% url 'account_logout' %}">Logout</a>
        {% else %}
        <a href="{% url 'account_login' %}">Login</a>
        {% endif %}
    8. 다시 관리자 페이지를 접속하여 소셜 계정에 등록되어 있는지 확인한다.


    • 회원가입을 할 때 사용자 이름 등록하기
    • django-allauth 문서 홈페이지/Signals 탭에서 관련 명령어를 확인할 수 있다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      # views.py
      from allauth.account.signals import user_signed_up
      from allauth.socialaccount.models import SocialAccount

      # 시그널이 발생했을 때 실행될 함수
      def naver_signup(request, user, **kwargs):
      social_user = SocialAccount.objects.filter(user=user)
      if social_user.exists():
      user.last_name = social_user[0].extra_data['name']
      user.save()

      # 시그널과 해당 함수를 connect
      # 시그널 연결 방법 2가지 receiver 쓰는 방법, connect 쓰는 방법
      user_signed_up.connect(naver_signup)
    • 관리자 페이지에서 인증 및 권한/사용자(들)에서 계정을 삭제하고 다시 만들어보자.

    • 이름이 등록되어 있는지 확인하자.
Share