values_list()는 Django 쿼리셋(QuerySet) 메서드 중 하나로, 데이터베이스에서 특정 필드들만 가져올 때 사용됩니다. 이 메서드는 특정 필드들에 대한 튜플들의 리스트를 반환합니다.

예시

# 예시 모델
class MyModel(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    gender = models.CharField(max_length=100)
    height = models.IntegerField()

# values_list() 사용
queryset = MyModel.objects.values_list('name', 'age')

위의 예시에서 values_list('name', 'age')MyModel 모델의 name 필드와 age 필드에 대한 데이터를 가져옵니다.

[('John', 25), ('Alice', 30), ('Bob', 22)]

즉, name 필드와 age 필드에 대한 튜플들의 리스트가 반환됩니다.

values_list()를 사용하면 쿼리셋에서 가져와야 할 필드들을 선택적으로 지정하여 데이터베이스에서 필요한 정보만 효율적으로 가져올 수 있습니다.

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

Serializer에서 method 사용하기  (0) 2023.08.27
Django에서의 Transactions  (0) 2023.08.26
annotate() 메서드와 가변 키워드 인자  (0) 2023.07.25
django에서 *args, **kwargs  (0) 2023.07.25
get_user_model()  (0) 2023.07.22

삽입 정렬 알고리즘(insertion sort algorithm)

삽입 정렬(insertion sort)은 리스트를 반복하면서 각 항목을 이미 정렬된 부분 리스트의 올바른 위치에 "삽입"함으로써 동작합니다.

  1. 리스트의 두 번째 항목에서 시작하여 왼쪽의 항목과 비교합니다.
  2. 현재 항목이 왼쪽 항목보다 작으면 왼쪽 항목을 오른쪽으로 이동시킵니다.
  3. 이를 현재 항목이 왼쪽 항목보다 크거나 왼쪽에 더 이상 항목이 없을 때까지 반복합니다.
  4. 그런 다음 현재 항목을 마지막으로 비어 있는 위치에 삽입합니다.
  5. 이 과정을 리스트의 모든 항목에 대해 반복합니다.

이를 파이썬 코드로 구현하면 다음과 같습니다:

def insertion_sort(arr: list[int]) -> list[int]:
    # 배열 전체를 반복하면서
    for i in range(1, len(arr)):
        key: int = arr[i]

        # 이미 정렬된 배열 부분에서 올바른 위치를 찾아가는 과정
        j: int = i - 1
        while j >=0 and key < arr[j] :
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key

    return arr


if __name__ == "__main__":
    arr: list[int] = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
    print(insertion_sort(arr))
    # [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

예를 들어, 이 함수에 [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] 배열을 전달하면,
31을 비교하고, 1 이 더 작으므로 순서를 바꿉니다. [1, 3, 4, 1, 5, 9, 2, 6, 5, 3, 5] 이렇게 바뀐 이후 3번째 인덱스인 4 를 비교하기 시작합니다. 41 보다 크므로 지나가고, 3 보다 크므로 지나갑니다. 이런 식으로 배열의 마지막 인덱스까지 정렬을 진행합니다.

삽입 정렬의 시간 복잡도는 최악의 경우 O(n^2)입니다. 그러나 리스트가 이미 거의 정렬되어 있는 경우 삽입 정렬은 매우 효율적일 수 있으며, 이 경우 시간 복잡도는 O(n)이 됩니다.

'Algorithms and Data Structures > Algorithms' 카테고리의 다른 글

Divide and Conquer(분할 정복)  (0) 2023.08.29
Brute Force  (0) 2023.08.15
재귀 함수(Recursive Function)  (0) 2023.08.13
선택 정렬 알고리즘  (1) 2023.07.29

선택 정렬 알고리즘(selection sort)

  1. 리스트 중에서 최소값을 찾습니다.
  2. 그 값을 리스트의 맨 앞에 위치한 값과 바꿉니다.
  3. 맨 처음 위치를 제외한 나머지 리스트를 대상으로 위의 과정을 반복합니다.

Python 코드

def selection_sort(arr: list[int]) -> list[int]:
    length: int = len(arr)
    # 배열 전체를 반복하면서
    for index_1 in range(length):
        min_index: int = index_1
        # 현재 위치에서 가장 작은 원소를 찾습니다.
        for index_2 in range(index_1 + 1, length):
            if arr[min_index] > arr[index_2]:
                min_index = index_2

        # 가장 작은 원소와 현재 원소를 교환합니다.
        arr[index_1], arr[min_index] = arr[min_index], arr[index_1]

    return arr


if __name__ == "__main__":
    arr: list[int] = [3, 1, 4, 9, 5, 7, 5]
    print(selection_sort(arr))
    # [1, 3, 4, 5, 5, 7, 9]

예를 들어, 이 함수에 [3, 1, 4, 9, 5, 7, 5] 배열을 전달하면,
31 을 비교해 1 이 더 작으므로 min_index은 0에서 1 의 위치정보인 1로 바뀝니다. 그리고 나머지 숫자들과 차례대로 비교합니다.
그러면 배열이 [1, 3, 4, 9, 5, 7, 5] 로 바뀝니다.
이러한 과정을 반복하면 배열 [1, 3, 4, 5, 5, 7, 9] 이라는 결과가 나옵니다.

선택 정렬의 시간 복잡도는 O(n^2)입니다. 이는 리스트의 모든 요소를 한 번씩 검사해야 하기 때문이며, 따라서 큰 리스트에서는 매우 느릴 수 있습니다.

'Algorithms and Data Structures > Algorithms' 카테고리의 다른 글

Divide and Conquer(분할 정복)  (0) 2023.08.29
Brute Force  (0) 2023.08.15
재귀 함수(Recursive Function)  (0) 2023.08.13
삽입 정렬 알고리즘  (0) 2023.07.29

annotate() 메서드는 Django 쿼리셋에서 사용되는 함수 중 하나로, 데이터베이스에서 집계된 값을 추가하는 데 사용됩니다. annotate() 메서드를 사용하면 원하는 필드 값을 가져오고 그 값을 기반으로 새로운 필드를 생성할 수 있습니다.

annotate(aggregate_expression, ...)
  • aggregate_expression: 필드 값을 계산하기 위한 집계 식을 지정합니다. 일반적으로 Django의 django.db.models 모듈에 있는 집계 함수들을 사용합니다. 예를 들어, Count(), Sum(), Avg(), Min(), Max() 등이 있습니다.

annotate() 메서드는 쿼리셋의 결과에 대해 각 필드 값에 대한 집계를 수행하고, 결과에 추가된 필드를 포함한 새로운 쿼리셋을 반환합니다. 이를 통해 집계된 값을 활용할 수 있습니다.

Book 모델이 있다고 가정하고, 이 모델은 다음과 같은 필드가 있다고 가정하겠습니다.(title, author, pages)
이때 각 저자가 쓴 책들의 총 페이지 수를 계산한다면 아래처럼 사용할 수 있습니다.

from django.db.models import Sum  # 집계 함수

total_pages_by_author = Book.objects.values("author").annotate(Sum("pages"))

이러면 각 저자별로 책들의 총 페이지 수를 계산하고 그 결과를 pages__sum이라는 이름의 필드로 추가합니다. 그러면 각 저자의 이름과 그 저자의 책들의 총 페이지 수를 담은 딕셔너리의 쿼리셋을 리턴합니다.

리턴되는 쿼리셋의 예시는 아래와 같습니다.

total_pages_by_author = [
    {
        'author': 1,   # 작가1의 id
        'pages__sum': 250,  # 작가1이 쓴 책들의 페이지 수 합산
    },
    {
        'author': 2,   # 작가2의 id
        'pages__sum': 400,  # 작가2가 쓴 책들의 페이지 수 합산
    }
]

만약 pages__sum이라는 필드명이 아닌 사용자가 정의한 필드명으로 구현하고 싶다면 아래 방식대로 구현하면 됩니다.

annotate(field_name=aggregate_expression)
  • field_name: 생성된 필드의 이름을 지정합니다.

from django.db.models import Sum

total_pages_by_author = Book.objects.values("author").annotate(total_pages=Sum("pages"))

이러면 리턴값에 추가되는 필드명이 total_pages가 됩니다.

리턴되는 쿼리셋의 예시는 아래와 같습니다.

total_pages_by_author = [
    {
        'author': 1,   # 작가1의 id
        'total_pages': 250,  # 작가1이 쓴 책들의 페이지 수 합산
    },
    {
        'author': 2,   # 작가2의 id
        'total_pages': 400,  # 작가2가 쓴 책들의 페이지 수 합산
    }
]

가변 키워드 인자

이 annotate() 함수를 공부하면서 의아한 점이 생겼습니다. anootate() 함수의 field_name은 어떤 인자인지가 궁금해졌습니다. 키워드 인자도 아니고 위치 인자도 아니고 지정한 이름에 따라 바뀌는 인자가 무엇이지 찾아보며 알게 된 결론은 "가변 키워드 인자"였습니다.

 

참고로 아래 두 링크를 읽고 오시면 다음 내용이 더 이해가 잘 되실겁니다.

위치 인자와 키워드 인자 : https://yesaroun.tistory.com/entry/Python-%EC%9C%84%EC%B9%98-%EC%9D%B8%EC%9E%90-%ED%82%A4%EC%9B%8C%EB%93%9C-%EC%9D%B8%EC%9E%90

 

Python) 위치 인자, 키워드 인자

파이썬에서 함수를 호출할 때, 인자(argument)를 전달하는 방법에는 두 가지가 있습니다. 위치인자(Positional Arguments)와 키워드 인자(Keyword Arguments)로 나뉩니다. 1. 위치 인자 (Positional Arguments) 위치 인

yesaroun.tistory.com

django에서 *args, **kwargs : https://yesaroun.tistory.com/entry/django%EC%97%90%EC%84%9C-args-kwargs

 

django에서 *args, **kwargs

Django와 같은 Python 기반 프레임워크에서 *args와 **kwargs는 함수나 메소드에 임의의 개수의 인자를 전달하는데 사용되는 문법입니다. *args: *args는 임의의 개수의 위치 인자를 함수나 메소드로 전달

yesaroun.tistory.com

 

annotate()는 키워드 인자를 받아서 새로운 필드 이름으로 사용하는 "키워드 인자 패킹"이라는 Python의 기능을 사용합니다.

아래의 예시가 가변 키워드 인자를 사용하는 예시입니다.

def func(**kwargs):
    for key, value in kwargs.items():
        print(f"{key} = {value}")

func(a=1, b=2)
# a = 1
# b = 2

이 예시는 단순하게 **kwargs 인자를 설명하는 예시일 수 있습니다. 하지만 이 예시 대로 annotate() 메서드의 가변 키워드 인자도 동일하게 동작합니다.

아래는 annotate()에서 사용되는 가변 키워드 인자 개념을 보기 쉽게 표현한 annotate_func() 코드입니다.

def annotate_func(**kwargs):
    # 이 경우 kwargs = {"total_pages": Sum("pages")}

    aggregates = kwargs  # 집계 표현식을 저장하는 딕셔너리

    for field, aggregate_expr in aggregates.items():
        # 각 키와 값을 출력합니다.
        print(f"필드명: {field}, 집계 표현식: {aggregate_expr}")

annotate_func(total_pages="Sum('pages')")
# 필드명: total_pages, 집계 표현식: Sum('pages')

만약 더 django의 annotate() 메소드 코드를 보고 싶으면 아래 코드를 확인해 주세요.
django 코드 링크 : https://github.com/django/django/blob/3.2/django/db/models/query.py

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

Django에서의 Transactions  (0) 2023.08.26
values_list()  (0) 2023.08.09
django에서 *args, **kwargs  (0) 2023.07.25
get_user_model()  (0) 2023.07.22
django 템플릿 <script>태그  (0) 2023.07.08

Django와 같은 Python 기반 프레임워크에서 *args**kwargs는 함수나 메소드에 임의의 개수의 인자를 전달하는데 사용되는 문법입니다.

  1. *args: *args는 임의의 개수의 위치 인자를 함수나 메소드로 전달하는데 사용됩니다. 이를 통해 함수나 메소드는 미리 정해지지 않은 개수의 인자를 받을 수 있습니다. *args는 튜플 형태로 인자를 전달받습니다.
  2. **kwargs : **kwargs는 임의의 개수의 키워드 인자를 함수나 메소드로 전달하는데 사용됩니다. 이를 통해 함수나 메소드는 미리 정해지지 않은 개수의 키워드 인자를 받을 수 있습니다.**kwargs\는 딕셔너리 형태로 인자를 전달받습니다.

참고 위치인자, 키워드 인자란 : https://yesaroun.tistory.com/entry/Python-%EC%9C%84%EC%B9%98-%EC%9D%B8%EC%9E%90-%ED%82%A4%EC%9B%8C%EB%93%9C-%EC%9D%B8%EC%9E%90

일반적인 사용 예시

1. *args의 사용 예시

def print_all_args(*args):
    for count, thing in enumerate(args):
        print('{}. {}'.format(count, thing))

print_all_args('apple', 'banana', 'cabbage')
# 0. apple
# 1. banana
# 2. cabbage

위의 코드는 print_all_args라는 함수를 정의하고 있습니다. 이 함수는 *args를 인자로 받아서, 넘겨받은 모든 인자를 출력합니다. 따라서 'apple', 'banana', 'cabbage' 세 가지 인자를 넘겨주면, 이 세 가지 모두를 출력합니다.

2. `kwargs`의 사용 예시**

def print_keyword_args(**kwargs):
    for key in kwargs:
        print('{}: {}'.format(key, kwargs[key]))

print_keyword_args(apple='fruit', cabbage='vegetable')
# apple: fruit
# cabbage: vegetable

위의 코드는 print_keyword_args라는 함수를 정의하고 있습니다. 이 함수는 **kwargs를 인자로 받아서, 넘겨받은 키워드 인자의 키와 값을 출력합니다. 따라서 'apple'과 'cabbage'라는 키와 각각의 값을 넘겨주면, 이 키와 값들을 출력합니다.

django에서 사용 예시

1. *args의 사용 예시

장고에서 *args**kwargs는 주로 URLconf에서 보낸 위치 인자와 키워드 인자를 뷰 메소드로 전달하는데 사용됩니다.

먼저, URLconf를 정의합니다

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path("articles/<int:year>/", views.YearArchiveView.as_view())
]

위의 URL 패턴에서 <int:year> 부분은 year라는 이름의 정수 변수를 캡처합니다.

이제 뷰에서 이 year 변수를 받아서 처리하는 코드를 작성합니다

# views.py
from django.http import HttpResponse
from django.views import View

class YearArchiveView(View):
    def get(self, request, *args, **kwargs):
        year = kwargs.get("year")
        return HttpResponse("Year archive: {}".format(year))

위의 코드에서 *args**kwargs는 URLconf에서 캡처한 변수를 받는 역할을 합니다. 여기서 kwargs.get("year")를 통해 year 변수를 가져오고 있습니다.

2. `kwargs`의 사용 예시**

장고(Django)에서 *args를 사용하는 상황은 비교적 드뭅니다. 왜냐하면 대부분의 경우에서 키워드 인자(**kwargs)가 더 명확하고 관리하기 쉽기 때문입니다. 키워드 인자를 사용하면 각 인자가 무엇을 의미하는지 명확히 알 수 있습니다.

그러나 *args는 어떤 함수나 메소드를 오버라이드(override)하거나 래핑(wrapper)하는 경우에 유용하게 사용할 수 있습니다. 예를 들어, Django에서 모델의 save 메소드를 오버라이드하는 경우에 *args를 사용할 수 있습니다

from django.db import models

class MyModel(models.Model):
    my_field = models.CharField(max_length=100)

    def save(self, *args, **kwargs):
        self.my_field = self.my_field.upper() # 대문자로 변환
        super().save(*args, **kwargs) # save() 메서드 오버라이드

여기서 *args**kwargs를 사용하면, 원래 save 메소드가 받아들일 수 있는 모든 인자를 그대로 전달할 수 있습니다. 따라서 *args**kwargs를 사용하면 원래의 save 메소드와 같은 인터페이스를 유지하면서 새로운 동작을 추가할 수 있습니다.

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

values_list()  (0) 2023.08.09
annotate() 메서드와 가변 키워드 인자  (0) 2023.07.25
get_user_model()  (0) 2023.07.22
django 템플릿 <script>태그  (0) 2023.07.08
Django ORM에서 던더(__)  (0) 2023.07.07

파이썬에서 함수를 호출할 때, 인자(argument)를 전달하는 방법에는 두 가지가 있습니다. 위치인자(Positional Arguments)와 키워드 인자(Keyword Arguments)로 나뉩니다.

1. 위치 인자 (Positional Arguments)

위치 인자는 함수 호출 시 전달하는 인자가 함수 정의에서 매개변수(parameter)의 위치에 따라 매핑되는 방식입니다. 즉, 인자의 순서가 함수 정의에서 매개변수의 순서와 일치해야 합니다. 위치인자를 사용할 때는 인자의 값을 순서대로 전달합니다.
일반적으로 인자를 정의하는 방식입니다.

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")

이 함수는 nameage라는 두 개의 매개변수를 받아서 인사말과 나이를 출력합니다. 이제 이 함수를 호출할 때 위치인자를 사용하면 다음과 같습니다.

greet("Alice", 30)

위의 호출은 name에 "Alice"라는 값이, 그리고 age에 30이라는 값이 매핑되어 함수가 실행됩니다.

2. 키워드 인자 (Keyword Arguments)

키워드 인자는 함수 호출 시 인자의 이름을 지정하여 함수 정의에서 해당 이름과 매핑되도록 전달하는 방식입니다. 이를 통해 인자의 순서를 신경 쓰지 않고 명확하게 어떤 값이 어떤 매개변수에 해당하는지 지정할 수 있습니다.

greet(age=30, name="Alice")

이렇게 키워드 인자를 사용하면 인자의 순서와 상관없이 nameage에 대해 명확하게 지정할 수 있습니다. 파이썬에서는 위치인자와 키워드 인자를 혼합하여 사용할 수도 있습니다. 하지만 키워드 인자를 사용하려면 위치인자가 먼저 나와야 합니다.

greet("Bob", age=25)

위의 호출은 name에 "Bob"이라는 위치 인자가 먼저 왔고, age에는 키워드 인자로 25가 전달되었습니다.
하지만, 이렇게 위치 인자와 키워드 인자를 혼합해서 사용하는 방식은 지양하는 것이 좋습니다.

'Python > Python' 카테고리의 다른 글

deque 모듈  (0) 2023.08.30
Python - isinstance()  (0) 2023.08.12
@classmethod 와 @staticmethod  (0) 2023.07.20
@property 데코레이터  (0) 2023.07.01
glob.glob() 함수  (0) 2023.06.11

Django에서 get_user_model() 함수는 현재 사용 중인 User 모델 클래스를 가져오는 데 사용되는 메서드입니다.

내장 User 모델

장고에 내장되어있는 User 모델을 사용하는 경우 get_user_model()django.contrib.auth.get_user_model() 함수를 호출하여 django.contrib.auth.models.User 클래스를 반환합니다.

예를 들어, User 모델에 대한 참조를 가져오기 위해 다음과 같이 get_user_model() 함수를 사용할 수 있습니다

from django.contrib.auth import get_user_model

User = get_user_model()

이렇게 하면 User 변수는 현재 활성화된 User 모델을 나타내게 됩니다.

사용자 정의 User 모델

get_user_model()함수는 사용자 정의 모델을 사용하는 경우에도 사용 가능합니다. 사용자 정의 User 모델을 구현하면, settings.py 파일에 AUTH_USER_MODEL 설정을 하는데 이렇게 하면 get_user_model()함수는 자동으로 사용자 정의 모델을 반환합니다.

# settings.py

AUTH_USER_MODEL = 'myapp.CustomUser'

이렇게 하면 get_user_model()myapp.CustomUser 클래스를 반환합니다.

인스턴스 메서드, 클래스 메서드, 정적 메서드 차이점

  1. 인스턴스 메서드(Instance Methods): 이 메서드들은 클래스의 객체 인스턴스에서 호출되며, 첫 번째 인자로 인스턴스 자체(self)를 받습니다. 인스턴스 변수에 접근하여 값을 읽거나 수정할 수 있습니다.
  1. 클래스 메서드(Class Methods): 클래스 메서드는 클래스에서 호출되며, 첫 번째 인자로 클래스(cls)를 받습니다. 이 메서드들은 클래스 변수를 수정하는 데 사용될 수 있습니다. 인스턴스에 대한 정보는 사용할 수 없습니다.

  2. 정적 메서드(Static Methods): @staticmethod 데코레이터로 표시된 메서드는 인스턴스나 클래스에 대한 참조 없이 동작합니다. 이 메서드들은 클래스나 인스턴스 상태를 수정할 필요가 없는 경우에 사용됩니다.

@classmethod

@classmethod 데코레이터는 메서드를 클래스 메서드로 표시하는 데 사용됩니다. 일반적인 인스턴스 메서드와 달리 클래스 메서드는 클래스 자체를 첫 번째 인자로 받습니다(일반적으로 cls로 표시됩니다), 그리고 객체 인스턴스가 아닌 클래스를 조작합니다.

예시

class MyClass:
    class_variable = "I am a class variable"

    def __init__(self, instance_variable):
        self.instance_variable = instance_variable

    def instance_method(self):
        print(f"Instance method, instance variable: {self.instance_variable}")

    @classmethod
    def class_method(cls):
        print(f"Class method, class variable: {cls.class_variable}")

    @staticmethod
    def static_method():
        print("Static method, no access to class or instance variables")


# 인스턴스 생성
my_instance = MyClass("I am an instance variable")

# 인스턴스 메서드 호출
my_instance.instance_method()  
# Instance method, instance variable: I am an instance variable

# 클래스 메서드 호출
MyClass.class_method()  
# Class method, class variable: I am a class variable

# 정적 메서드 호출
MyClass.static_method()  
# Static method, no access to class or instance variables

@classmethod는 주로 클래스 변수를 조작하거나, 클래스에 대한 상태를 변경할 때 사용됩니다. 또한, 인스턴스를 생성하지 않고도 클래스의 기능을 사용할 수 있게 해줍니다.

@staticmethod

@staticmethod 데코레이터는 메서드를 정적(static) 메서드로 지정합니다. 정적 메서드는 클래스와 관련이 있지만 클래스나 인스턴스의 상태에 영향을 받지 않으며, 인스턴스 메서드와 달리 selfcls와 같은 첫 번째 매개변수를 갖지 않습니다.

따라서 @staticmethod를 사용하여 정의된 메서드는 클래스의 인스턴스 없이도 호출할 수 있으며, 클래스 내부의 다른 메서드나 속성에 접근할 수 있습니다.

아래 예시 코드에서 @staticmethod를 사용한 이유는 Serializer 클래스의 serialize() 메서드를 클래스 메서드로 정의하고자 했기 때문입니다. @staticmethod를 사용하면 serialize() 메서드를 인스턴스화하지 않고도 직접 호출할 수 있으며, 클래스 내부의 다른 메서드나 속성에 접근할 수 있습니다.

class UserSerializer:
    @staticmethod
    def serialize(user):
        # 직렬화 로직
        return serialized_data

이렇게 하면 UserSerializer.serialize(user)와 같은 형태로 메서드를 호출할 수 있습니다.

정적 메서드는 클래스의 상태와 관련이 없는 유틸리티 메서드를 정의하거나, 클래스와 밀접한 연관이 있는 로직을 모듈화하고 싶을 때 유용하게 사용될 수 있습니다.

'Python > Python' 카테고리의 다른 글

Python - isinstance()  (0) 2023.08.12
Python) 위치 인자, 키워드 인자  (0) 2023.07.25
@property 데코레이터  (0) 2023.07.01
glob.glob() 함수  (0) 2023.06.11
Python 라이브러리 - functools  (0) 2023.05.24

장고 템플릿을 이용하는 프로젝트 진행 중에 대시보드를 구현해야 했습니다.

대시보드 한 페이지에 다양한 정보가 들어오고 컴포넌트 별로 실시간 업데이트가 필요하지 않을까라는 생각에 ajax로 통신을 하려고 했습니다.

ajax로 통신할 때 url 정보를 보내줘야 하는데 장고 url 태그가 편리하기에 이 장고 코드를 <script> 태그 내에 작성해도 되는지 알아보았습니다.

<script> 태그 내부의 장고 코드

<script> 태그 내부에도 Django 템플릿 태그를 사용할 수 있습니다. 하지만 여기서 주의할 점은 Django 템플릿 태그가 서버 측에서 처리되고, JavaScript 코드는 클라이언트 측에서 실행된다는 것입니다.

예를 들어, Django의 URL을 JavaScript 코드에서 사용하고 싶을 때, 이렇게 할 수 있습니다

<script>
  let listDataUrl = "{% url 'list_data_url' %}";
  let graphDataUrl = "{% url 'graph_data_url' %}";

  // 이후에 이 URL들을 AJAX 요청에서 사용
  // ...
</script>

위의 예제에서, Django 템플릿 태그는 서버 측에서 URL을 생성하고, 이 URL은 JavaScript 변수에 할당됩니다. 이후에 이 변수들을 사용하여 AJAX 요청을 수행할 수 있습니다.

주의할 점

여기서 주의할 점은 Django 템플릿 태그가 서버 측에서 처리되고, JavaScript 코드는 클라이언트 측에서 실행된다는 것입니다.

웹 애플리케이션에서 서버 측과 클라이언트 측은 다른 환경에서 실행되며, 서로 다른 역할을 수행합니다.

서버 측(Server-Side)

  • 서버 측은 웹 서버와 백엔드 애플리케이션 로직이 실행되는 곳입니다.
  • 데이터베이스 쿼리, 인증, 데이터 처리 등과 같은 작업을 처리합니다.
  • Django는 서버 측 웹 프레임워크로, 요청이 들어오면 이에 대한 응답을 생성하는 데 사용됩니다.
  • Django 템플릿 태그는 서버에서 해석되고 처리됩니다. 템플릿 태그는 서버 측에서 HTML 문서를 렌더링 하는데 도움이 됩니다.

클라이언트 측(Client-Side)

  • 클라이언트 측은 사용자의 브라우저에서 실행되는 환경입니다.
  • HTML, CSS, JavaScript로 구성된 웹 페이지를 렌더링 하고, 사용자와 상호작용합니다.
  • JavaScript는 클라이언트 측에서 실행되며, 동적인 기능을 제공합니다 (예: 버튼 클릭, AJAX 요청, 애니메이션 등).

서버 측과 클라이언트 측의 관계

  • 사용자가 웹 페이지를 요청하면, 서버 측(Django)은 HTML 문서를 생성하여 브라우저로 보냅니다.
  • 이 HTML 문서는 Django 템플릿 태그로 작성되었을 수 있으며, 이 태그들은 서버에서 처리되고 최종 HTML로 변환됩니다.
  • 브라우저(클라이언트 측)는 이 HTML 문서를 받아 사용자에게 표시하며, JavaScript는 브라우저에서 실행됩니다.

이렇게 서버 측에서 렌더링 된 결과를 클라이언트 측에서 사용할 수 있습니다. 하지만 JavaScript 코드 자체는 클라이언트에서 실행되기 때문에, 실행 시점에 서버 측에 영향을 미치지는 않습니다.

그래서 script 함수 내부에서는 장고 템플릿 코드를 사용할 수 없습니다.

<script>
$(document).ready(function(){
  function renderList() {
    $.ajax({
      url: "{% url 'list_data_url' %}"; // 이렇게 사용 할 수 없습니다.
      // 생략...
    });
  }
});
</script>

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

django에서 *args, **kwargs  (0) 2023.07.25
get_user_model()  (0) 2023.07.22
Django ORM에서 던더(__)  (0) 2023.07.07
Type hint 적용후 circular dependency 문제 해결법  (0) 2023.06.30
FK 관계를 설정하는 방법  (0) 2023.06.30

언더스코어 두 개 (__)는 Django ORM에서 사용되는 문법입니다. 이를 "던더" 또는 "더블 언더스코어"라고도 합니다.

__를 사용하여 필드 이름과 조건을 연결하여 데이터베이스 쿼리를 구성할 수 있습니다. 이를 통해 관련된 모델들 간의 관계를 표현하고, 필터링 또는 관련된 데이터를 가져올 수 있습니다.

예를 들어,
모델의 구조는 아래와 같습니다.

class Department(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    is_it = models.BooleanField(default=False)
    explain = models.CharField(max_length=255, blank=True, default="")


class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True)
    # ... 생략 ...

이 경우 it 부서의 유저 프로필만 가져온다면 아래와 같이 작성할 수 있습니다.

user_profiles = UserProfile.objects.filter(
    department__is_it=True
)

department__is_it=TrueUserProfiledepartment 필드의 is_it 속성을 필터링하는 부분입니다. __을 사용하여 관련된 모델인 Departmentis_it 필드에 접근하고 비교 조건을 설정합니다.

즉, __를 사용하면 관련된 모델 간의 필드를 참조하고, 관련된 데이터를 가져오는 데 사용할 수 있습니다.

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

get_user_model()  (0) 2023.07.22
django 템플릿 <script>태그  (0) 2023.07.08
Type hint 적용후 circular dependency 문제 해결법  (0) 2023.06.30
FK 관계를 설정하는 방법  (0) 2023.06.30
(Django) reverse와 reverse_lazy 차이  (0) 2023.06.23