Django code snippet 저장소 - 유용한 파이썬 코드들 모음

말그대로 장고 쓰다가 찾아보게 되는 코드 조각들을 여기에 저장해 둬 보자. 위키처럼 쭉 저장해둔다. 테마가 될때까지

 

timedelta 값 template에서 표기하기

가장 쉬운 솔루션으로 가자.

https://stackify.dev/332647-displaying-a-timedelta-object-in-a-django-template

 

Displaying a timedelta object in a django template - Stackify

I followed Peter's advice and wrote a custom template filter. Here's the steps I took. First I followed this guide to create a custom template filter. Be sure to read...

stackify.dev

템플릿으로 보내기 전에 마이크로세컨드 microseconds 부분을 제거해 보내면 그나마 볼 만하다.

time = time - datetime.timedelta(microseconds=time.microseconds)

결과는,

4 days, 3:10:15

이런식으로 보이게 된다.

 

게시물 페이지 기능 넣기

그 많은 정보들 중에 종합판을 여기에 기록해 둔다.

처음, 마지막, 이전, 다음 페이지 기능이 전체로 다 들어가 있는 이거 좋다

아래 링크 답글 중에 

Farid Chowdhury 이분이 쓴 글을 찾아서 활용하시길...

https://stackoverflow.com/questions/30864011/display-only-some-of-the-page-numbers-by-django-pagination

     <nav aria-label="Page navigation example">
        <ul class="pagination justify-content-center">

            <li class="page-item {% if not page_obj.has_previous %} disabled {% endif %}">
                <a class="page-link" href="?page=1" tabindex="-1">FIRST</a>
            </li>
            <li class="page-item {% if not page_obj.has_previous %} disabled {% endif %}">
                <a class="page-link" href="{% if page_obj.has_previous %}?page={{ page_obj.previous_page_number }}{% endif %} " tabindex="-1">Previous</a>
            </li>

            {% if page_obj.number|add:'-4' > 1 %}
                <li class="page-item disabled"><a class="page-link" href="?page={{ page_obj.number|add:'-5' }}">&hellip;</a></li>
            {% endif %}

            {% for i in page_obj.paginator.page_range %}
                {% if page_obj.number == i %}
                    <li class="active page-item disabled"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
                {% elif i > page_obj.number|add:'-5' and i < page_obj.number|add:'5' %}
                    <li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
                {% endif %}
            {% endfor %}

            {% if page_obj.paginator.num_pages > page_obj.number|add:'4' %}
                <li class="page-item disabled"><a class="page-link" href="?page={{ page_obj.number|add:'5' }}">&hellip;</a></li>
            {% endif %}

            <li class="page-item {% if not page_obj.has_next %} disabled {% endif %}">
                <a class="page-link" href="{% if page_obj.has_next %} ?page={{ page_obj.next_page_number }} {% endif %}">Next</a>
            </li>
            <li class="page-item {% if not page_obj.has_next %} disabled {% endif %}">
                <a class="page-link" href="{% if page_obj.has_next %} ?page={{ page_obj.paginator.num_pages }}  {% endif %}">LAST</a>
            </li>
        </ul>
    </nav>

 

변수를 이용하여 DB 필드이름 값 사용하기

당연히 될 것 같은데 DB 필드명 대신 변수에 스트링 값을 넣어서 사용하는게 쉽지 않네.

정답은 아래 링크에서 추출

https://stackoverflow.com/questions/9122169/calling-filter-with-a-variable-for-field-name

To use field name string with icontains. Try this

field_name = 'video'
field_name_icontains = field_name + '__icontains'
Playlist.objects.filter(**{field_name_icontains: v})

 

 

데코레이터로 에러 메시지 출력 하기

좀 더 원하는 형태로 메시지를 출력하도록 예외가 발생하면 처리하도록 데코레이터로 작성한다.

https://data-newbie.tistory.com/402

 

[ Python ] decorator로 Error 정리해서 출력하기

광고 한번만 눌러주세요. 블로그 운영에 큰 힘이 됩니다! 파이썬 코드를 돌리다 에러가 나게 되면 다음과 같이 에러가 보일 것이다. 이런 식으로 Traceback 코드로 나오게 된다. 의미는 error_test.py에

data-newbie.tistory.com

 

장고 템플릿 내에서 날짜 비교하기

오늘과 비교해서 어떤 기능을 수행하고 싶다면, 특히 템플릿 내에서 아래 코드를 꼭 참고

{% now "Y-m-d" as todays_date %}
{% if todays_date < someday|date:"Y-m-d" %}
   <h1>It's not too late!</h1>
{% endif %}

https://stackoverflow.com/questions/3798812/how-to-compare-dates-in-django-templates

완전 좋음

 

문자열 NULL 제거하기

요거 간단하지만 유용한

text_it = text_it.replace('\0', 'null').replace('\x00', 'null')

https://stackoverflow.com/questions/51782114/python-replace-0-in-string-with-null 

 

model 선언시 자동으로 정렬되도록

정렬은 할때 마다 해야하지만, 기본적인 정렬을 설정할 수 있다.

아래 처럼 해보자.

https://moondol-ai.tistory.com/404

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

...
    def __str__(self):
        return self.content
    
    # 정렬 조건 추가
    class Meta:
        ordering = ['-id']

 

ajax CSRF 에러 발생시

CSRF 라고 찾으면 엄청 많은 정보들이 쏟아진다. 머 그중에 하나만...

https://codong.tistory.com/28

 

[django] Forbidden (CSRF token missing or incorrect.) 해결하기!

😄 개요 간만에 장고로 다시 개인적인 toy project를 해보고 싶어서, 장고 프로젝트 생성하고 간단하게 POST 요청 비동기통신을 이용해보고 싶어서 jquery의 ajax를 사용했다. 역시, ERROR가 안뜰리 없다

codong.tistory.com

<script>
  $.ajaxSetup({
    headers: { "X-CSRFToken": '{{csrf_token}}' }
  });
</script>

 

request.FILES 에서 파일이름 가져오기

요거 리스트로 가지고 있어서 아래 처럼 뽑으면 되는데, 

함정은 filename 이 파일이름이 아니라느거 아래 코드에서 file 이 파일명이다.

print(request.FILES.items())
for filename, file in request.FILES.items():
	print(filename, file, file.name, file.content_type, file.size)

출력 결과는

폼 객체 이름이 content 였고, 실제 파일 명은 그다음에 있는 sns_face.png 라는 것

(<input type="file" name="content" id="id_content"> 이렇게 폼을 보내 줬음)

<generator object MultiValueDict.items at 0x000002F127859040>
content sns_face.png sns_face.png image/png 9051

 

파이썬 enum 사용하기

문서 종류나 타입을 정할때 상수를 쓰는데 한계가 있다. Enum 을 활용하자

 

🌈 https://greendreamtrre.tistory.com/358

> Enum을 상속 받는 클래스를 만듭니다.

from enum import Enum

class Rainbow(Enum):
    Red = 0
    Orange = 1
    Yellow = 2
    Green = 3
    Blue = 4
    Navy = 5
    Purple = 6

 

보통 외부에 변수에 넣고는 integer 로 활용하기 쉬운때 이때를 위해서는 __int__ 함수를 오버라이딩 해두자.

🌈 https://newbedev.com/convert-enum-to-int-in-python

# using aenum
from aenum import Enum, MultiValue

class Nationality(Enum):
    _init_ = 'value fullname'
    _settings_ = MultiValue

    PL = 0, 'Poland'
    DE = 1, 'Germany'
    FR = 2, 'France'

    def __int__(self):
        return self.value

 

데코레이터 클래스 적용하기

이렇게

https://stackoverflow.com/questions/34217400/function-object-has-no-attribute-as-view

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):

 

redirect 이전 페이지로

https://stackoverflow.com/questions/35796195/how-to-redirect-to-previous-page-in-django-after-post-request

 

템플릿에서 다음과 같이 next 를 쿼리로 넘겨준다.

<a href="{% url 'user_update' %}?next={{ request.path }}">Update User</a>

이걸 받아서 처리한다.

class UserUpdateView(UpdateView):
    ...
    def get_success_url(self):
        return self.request.GET.get('next', reverse('home'))

 

혹은 더 쉬운 방법으로,

You can use this

return redirect(request.META.get('HTTP_REFERER'))

Make sure to import this

from django.shortcuts import redirect

 

 

폼셋 동적으로 개수 늘이기

폼셋을 몇개로 고정하지 말고, 동적으로 버튼을 누를 때 마다 하나씩 추가되도록 하는 코드 예제이다. 완전 유용한 링크

https://www.brennantymrak.com/articles/django-dynamic-formsets-javascript.html

 

Dynamically Add Forms in Django with Formsets and JavaScript

This tutorial demonstrates how multiple copies of a form can be dynamically added to a page and processed using Django formsets and JavaScript. In a web app, a user may need to submit the same form multiple times in a row if they are inputting data to add

www.brennantymrak.com

 

템플릿에서 for iteration counter 값 보기

 

https://stackoverflow.com/questions/11481499/django-iterate-number-in-for-loop-of-a-template

Django provides it. You can use either:

  • {{ forloop.counter }} index starts at 1.
  • {{ forloop.counter0 }} index starts at 0.

 

 

폼 값 체크

 

https://wayhome25.github.io/django/2017/05/06/django-form/

# myapp/forms.py
from django import forms

def min_length_3_validator(value):
	if len(value) < 3:
		raise forms.ValidationError('3글자 이상 입력해주세요')


class PostForm(forms.Form):
	title = forms.CharField(validators=[min_length_3_validator]) # 한줄 문자입력창, 커스텀 validators 옵션 지정 가능

 

페이지, 결과 나누기 기능


템플릿 페이지에서 페이지 기능??  원하는 갯수만큼 가져오기

 

  {% for object in item.img_url.all|slice:"1:7" %}
 	{{object}} 		
  {% endfor %}

위 코드와 같이 

| slice : ":5" 이런식으로 나타내면 됩니다.

출처: https://kgu0724.tistory.com/212 [병아리 개발자의 이야기]

 


잘모아둬 코드 조각들

Markus Spiske 님의 사진, 출처: Pexels