말그대로 장고 쓰다가 찾아보게 되는 코드 조각들을 여기에 저장해 둬 보자. 위키처럼 쭉 저장해둔다. 테마가 될때까지
timedelta 값 template에서 표기하기
가장 쉬운 솔루션으로 가자.
https://stackify.dev/332647-displaying-a-timedelta-object-in-a-django-template
템플릿으로 보내기 전에 마이크로세컨드 microseconds 부분을 제거해 보내면 그나마 볼 만하다.
time = time - datetime.timedelta(microseconds=time.microseconds)
결과는,
4 days, 3:10:15
이런식으로 보이게 된다.
게시물 페이지 기능 넣기
그 많은 정보들 중에 종합판을 여기에 기록해 둔다.
처음, 마지막, 이전, 다음 페이지 기능이 전체로 다 들어가 있는 이거 좋다
아래 링크 답글 중에
Farid Chowdhury 이분이 쓴 글을 찾아서 활용하시길...
<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' }}">…</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' }}">…</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
장고 템플릿 내에서 날짜 비교하기
오늘과 비교해서 어떤 기능을 수행하고 싶다면, 특히 템플릿 내에서 아래 코드를 꼭 참고
{% 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 라고 찾으면 엄청 많은 정보들이 쏟아진다. 머 그중에 하나만...
<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 이전 페이지로
템플릿에서 다음과 같이 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
템플릿에서 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