[Django] Django ORM, 자주 사용되는 명령어

のの·2022년 3월 25일
2

Django

목록 보기
3/5

코멘토 부트캠프의 Django 개발 실무과정을 듣고 배웠던 내용을 주차별로 나누어 정리해보려합니다.

코멘토 직무 부트캠프 바로가기


하나의 글에 배웠던 모든 내용과 코드를 작성할 경우 글이 너무 길어지기 때문에 핵심적인 내용만 요약해서 정리할 예정입니다. 과정을 마무리하는 단계에서 지금(현재 6주차)까지 배웠던 내용을 주제별로 나눈다면 다음과 같습니다.

week1: Django가 무엇인지, 가상환경, 프로젝트 세팅에 관하여
week2: Model, View, Template, 템플릿 상속
week3: ORM,
week4: FBV, CBV
week5: Authentication
week6: AWS 배포


ORM

ORM은 Object Relation Mapper의 약자입니다. Django ORM은 데이터베이스와 상호작용하는 강력하고 우아한 방법입니다. Django ORM은 SQL 명령문이 아닌 비교적 간단한 파이썬 명령문으로 데이터베이스를 다룰 수 있는 추상화된 레이어입니다. 최종적으로 Django ORM은 모든 작업을 SQL 문으로 변환합니다. 이 포스팅에서는 일반적인 SQL 쿼리의 ORM에 대해 알아보겠습니다.

Django ORM은 관계형 데이터베이스 관리 시스템중에 널리 사용되는 PostgreSQL, MySQL, Oracle, sqlite3 등의 RDBMS를 Wrapping하여 사용할 수 있습니다. Django ORM 명령어를 통해 다양한 데이터베이스 시스템을 제어할 수 있습니다.

Django Shell

데이터베이스의 모델 인스턴스를 Django shell을 통해 제어할 수 있습니다. 아래의 명령어를 실행하면 Python shell 처럼 동작합니다.

python manage.py shell


자주 사용되는 ORM 명령어

User 스키마를 가지는 테이블을 생성하고 데이터베이스의 데이터를 표와 같이 추가합니다.

# member/models.py

from django.db import models
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    city = models.CharField(max_length=255)

idnameagecity
1lee20seoul
2kim25busan
3park30daegu

  1. 조회
  • User 테이블의 id가 1인 데이터를 조회하는 경우

    User.objects.filter(id=1)
  • User 테이블의 모든 인스턴스 조회

    User.objects.all()
    	
    
  1. 생성
  • name="choi", age=35, city="daejeon"이란 데이터를 추가하는 경우

    u = User.objects.create(name="choi", age=35, 	city="daejeon")
    u.save()
    
    혹은
    
    u = User(name="choi", age=35, city="daejeon")
    u.save(force_insert=True)
  1. 수정
  • id=1인 인스턴스의 age를 21로 변경하는 경우
    u = User.objects.get(pk=1)
    u.age = 21
    u.save()
  1. 삭제
  • id=1인 인스턴스 삭제

    User.objects.get(pk=1).delete()
    
  • User의 모든 인스턴스 삭제

    User.objects.all().delete()
    
  1. Null Value
  • ‘__isnull’은 Null value를 체크하는 ORM 문법이고 True, False를 리턴한다.

    User.objects.filter(age__isnull=True).values('id','age')
    <QuerySet []>
    
    User.objects.filter(age__isnull=False).values('id','age')
    <QuerySet [{'id': 1, 'age': 20}, {'id': 2, 'age': 25}, {'id': 3, 'age': 30}]>
  1. exists()
  • queryset을 확인하려면 exists() 메서드를 사용합니다. queryset 에 결과가 포함되어 있으면 True를 반환하고, 포함되어 있지 않으면 False를 반환합니다.

    User.objects.filter(age__isnull=True).values('id','age').exists()
    False
    
    User.objects.filter(age__isnull=False).values('id','age').exists()
    True
  1. LIKE

    User.objects.filter(city__contains='city').values('id','city')
    <QuerySet [{'id': 1, 'city': 'city1'}, {'id': 2, 'city': 'city2'}, {'id': 3, 'city': 'city3'}]>
  • 위 쿼리에서 __contains는 city 열의 'city' 하위 문자열을 검색하는 데 사용됩니다. 또한 __exact를 사용하여 정확히 일치하는지를 확인할 수 있습니다.

    User.objects.filter(city__exact='city').values('id','city')
    <QuerySet []>
  1. __startswith , __endswith

    User.objects.filter(city__startswith='city').values('id','city')
    <QuerySet [{'id': 1, 'city': 'city1'}, {'id': 2, 'city': 'city2'}, {'id': 3, 'city': 'city3'}]>
    
    User.objects.filter(city__startswith='ity').values('id','city')
    <QuerySet []>
    
    User.objects.filter(city__endswith='2').values('id','city')
    <QuerySet [{'id': 2, 'city': 'city2'}]>
  1. 비교
  • gt - Greater than.

  • gte - Greater than or equal to.

  • lt - Less than.

  • lte - Less than or equal to.

        User.objects.filter(age__gt=20).values('id','age')
        <QuerySet [{'id': 2, 'age': 25}, {'id': 3, 'age': 30}]>
    
        User.objects.filter(age__gte=20).values('id','age')
        <QuerySet [{'id': 1, 'age': 20}, {'id': 2, 'age': 25}, {'id': 3, 'age': 30}]>
    
        User.objects.filter(age__lt=25).values('id','age')
        <QuerySet [{'id': 1, 'age': 20}]>
    
        User.objects.filter(age__lte=25).values('id','age')
        <QuerySet [{'id': 1, 'age': 20}, {'id': 2, 'age': 25}]>
    
  1. 특정 칼럼 선택

    User.objects.values('id')
    <QuerySet [{'id': 1}, {'id': 2}, {'id': 3}]>
    
    User.objects.values('id','first_name','last_name')
    <QuerySet [{'id': 1, 'first_name': 'sample', 'last_name': '1'}, {'id': 2, 'first_name': 'sample', 'last_name': '2'}, {'id': 3, 'first_name': 'sample', 'last_name': '3'}]>
    
  2. IN

  • __in 은 Multiple values를 필터링하기 위해 사용된다.

    User.objects.filter(id__in=[1,2])
    <QuerySet [<User: User object (1)>, <User: User object (2)>]>
    
  1. exclude()
  • 조회 매개 변수와 일치하는 개체를 queryset에서 제외합니다.

    User.objects.exclude(id=1)
    <QuerySet [<User: User object (2)>, <User: User object (3)>]>
  1. Aiias, AS
  • extra() 메서드는 ORM 컬럼의 이름을 변경하기 위해 사용됩니다.

    User.objects.extra(select={'FirstName':'first_name','LastName':'last_name'}).values('FirstName','LastName')
    <QuerySet [{'FirstName': 'sample', 'LastName': '1'}, {'FirstName': 'sample', 'LastName': '2'}, {'FirstName': 'sample', 'LastName': '3'}]>
  1. Group By
  • aggregate() 함수는 sum, average, min, max 등의 집계 연산을 실행하기 위해 사용됩니다.

    User.objects.aggregate(Sum('age'))
    {'age__sum': 75}
    
    User.objects.aggregate(Avg('age'))
    {'age__avg': 25.0}
    
    User.objects.aggregate(Max('age'))
    {'age__max': 30}
    
    User.objects.aggregate(Min('age'))
    {'age__min': 20}
  1. aggregate()
  • aggregate 함수는 전체 데이터 집합에서만 작동합니다. 도시별 평균 연령 그룹을 원할 경우 aggregate() 대신 annotate()를 사용합니다.

    User.objects.values('city').annotate(Sum('age'))
    <QuerySet [{'city': 'city1', 'age__sum': 20}, {'city': 'city2', 'age__sum': 25}, {'city': 'city3', 'age__sum': 30}]>
    
  1. Order by

    User.objects.values('city').annotate(total_age=Sum('age')).order_by('-total_age')
    <QuerySet [{'city': 'city3', 'total_age': 30}, {'city': 'city2', 'total_age': 25}, {'city': 'city1', 'total_age': 20}]>
  2. 출력의 기본 이름을 변경

  • total_age라는 이름을 변경하고 total_age에 order_by를 사용합니다. '-total_age'는 내림차순으로 사용됩니다.

  • 일반적으로 데이터베이스에서는 쿼리별로 그룹에 'HAVING' 절을 사용합니다. Django에서는 filter() 함수를 사용할 수 있습니다.

    User.objects.values('city').annotate(total_age=Sum('age')).filter(total_age__gt=20).order_by('-total_age')
    <QuerySet [{'city': 'city3', 'total_age': 30}, {'city': 'city2', 'total_age': 25}]>
  1. Q 객체를 사용한 필터링
  • Q 객체는 AND, OR 및 NOT 연산에 사용됩니다.

  • AND
    ‘&’ is used for AND operation between 2 Q expressions.

    User.objects.filter(Q(city='city1') & Q(age=25)).values('id','city','age')
    <QuerySet []>
    
    User.objects.filter(Q(city='city1') & Q(age=20)).values('id','city','age')
    <QuerySet [{'id': 1, 'city': 'city1', 'age': 20}]>
  • OR

      User.objects.filter(Q(city='city1') | Q(age=25)).values('id','city','age')
      <QuerySet [{'id': 1, 'city': 'city1', 'age': 20}, {'id': 2, 'city': 'city2', 'age': 25}]>
  • NOT
  User.objects.filter(Q(city='city1') & ~Q(age=20)).values('id','city','age')
  <QuerySet []>

  User.objects.filter(Q(city='city2') & ~Q(age=20)).values('id','city','age')
  <QuerySet [{'id': 2, 'city': 'city2', 'age': 25}]>
  1. F() Expressions
  • Django QuerySet API에서 F() 표현은 데이터베이스의 모델 필드 값을 직접 참조하기 위해 사용됩니다.

      User.objects.annotate(new_age=F('age')*2).values('id','age','new_age')
      <QuerySet [{'id': 1, 'age': 20, 'new_age': 40}, {'id': 2, 'age': 25, 'new_age': 50}, {'id': 3, 'age': 30, 'new_age': 60}]>
    
      User.objects.filter(id__lt=F('age')).values('id','age')
      <QuerySet [{'id': 1, 'age': 20}, {'id': 2, 'age': 25}, {'id': 3, 'age': 30}]>
    
      User.objects.filter(id__gt=F('age')).values('id','age')
      <QuerySet []>

수업화면

profile
wannabe developer

0개의 댓글