Framework/Django

_meta

JM Lee 2023. 12. 17. 15:23
728x90

Django의 _meta API는 모델 클래스의 메타데이터에 접근할 수 있게 해주는 기능이다. 이 API를 사용하면 모델의 속성, 필드 및 다양한 메타 정보에 프로그래밍적으로 접근할 수 있다.

 

_meta 속성은 보통 일상적인 웹 애플리케이션 개발에서는 직접적으로 _meta를 사용할 일이 많지 않다. 대부분의 경우에는 간단한 쿼리와 모델 정의만으로 충분하다. 하지만 특정 상황에서 _meta를 사용하는 것이 유용할 수 있다.

  1. 동적 쿼리 빌드
  2. 모델 간 관계 탐색
  3. 일반화된 코드 작성
  4. 앱 내 모델 동적 처리
  5. 프로젝트 유틸리티 및 도구 개발
  6. 정보 가져오는 방식 상수로 남기기

1번에 대한 예시

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    category = models.CharField(max_length=50)
from django.db.models import Q

def dynamic_query_builder(filters):
    """
    동적으로 쿼리를 빌드하는 함수
    :param filters: 사용자로부터 받은 필터 조건
    :return: 필터된 쿼리셋
    """
    query = Q()  # 빈 쿼리 객체

    # 사용자로부터 받은 필터 조건을 동적으로 처리
    for field_name, value in filters.items():
        # 모델의 필드가 존재하는지 확인
        if field_name in Product._meta.get_fields():
            # 필드가 존재하면 해당 필드에 대한 조건을 Q 객체에 추가
            query |= Q(**{f"{field_name}__icontains": value})

    # 최종적으로 필터된 쿼리셋 반환
    return Product.objects.filter(query)

 

이제 동적 쿼리 빌드를 생성하면 된다. 

filters = {"name": "Laptop", "price__lte": 1000}
result = dynamic_query_builder(filters)

2번에 대한 예시

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    published_date = models.DateField()
def get_books_by_author(author_name):
    """
    작가의 이름을 받아서 해당 작가가 쓴 책들을 가져오는 함수
    :param author_name: 작가의 이름
    :return: 작가와 작가가 쓴 책들의 정보
    """
    # 작가 이름을 기반으로 작가 객체를 가져옴
    author = Author.objects.get(name=author_name)

    # 작가 객체를 사용하여 작가가 쓴 책들을 가져옴
    books_by_author = Book.objects.filter(author=author)

    # 결과 반환
    return {
        "author": author,
        "books": books_by_author
    }

 

여기에 _meta 함수를 사용하면 다음과 같은 코드가 나타난다.

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    published_date = models.DateField()

def get_books_by_author_using_meta(author_name):
    """
    작가의 이름을 받아서 해당 작가가 쓴 책들을 _meta를 사용하여 조회하는 함수
    :param author_name: 작가의 이름
    :return: 작가와 작가가 쓴 책들의 정보
    """
    # 작가 모델의 _meta를 사용하여 작가의 이름 필드를 찾음
    author_name_field = Author._meta.get_field('name')

    # 해당 필드를 사용하여 작가 이름에 대한 쿼리를 생성
    query = {f"{author_name_field.name}__icontains": author_name}

    # 쿼리를 사용하여 작가가 쓴 책들을 가져옴
    books_by_author = Book.objects.filter(**query)

    # 결과 반환
    return {
        "author_name": author_name,
        "books": books_by_author
    }

 

확실히 요즘 많이 쓰고 있는 filter() 함수에 비해 직관적이지 않은 것 같다. 그래서 지금까지 쓸 일이 잘 없었나 보다.

그러나 앞에서 설명한 대로, 동적 모델의 메타데이터에 접근하는 등 특수한 경우에는 아직까지 _meta를 사용하는 듯하다.

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

HTTP POST 요청 시 headers 매개변수  (0) 2024.01.01
Django Template Engine은 무엇이고 어떤 기능을 제공합니까?  (1) 2023.12.18
ORM이란?  (0) 2023.12.16
reverse, reverse_lazy  (0) 2023.12.16
DRF manage.py 해석  (0) 2023.10.31