Skip to content

Instantly share code, notes, and snippets.

@kuzminT
Last active October 7, 2018 20:50
Show Gist options
  • Save kuzminT/b08f7734953bee49485efaa153151aa3 to your computer and use it in GitHub Desktop.
Save kuzminT/b08f7734953bee49485efaa153151aa3 to your computer and use it in GitHub Desktop.
Django tips

Работа с формами

Работа с формами в официальном руководстве для Django 2:

Добавление классов и атрибутов к ModelForm.

Если нужно навесить классы или изменить атрибуты для рендеринга полей формы, использующей ModelForm, то проще всего переопределить __init__.

class CommentForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['name'].widget.attrs.update({'class': 'special'})
    self.fields['comment'].widget.attrs.update(size='40')

В некоторых случаях вместо определённой, заданной заранее формы удобнее создавать формы для изменения и создания новых моделей "на лету", используя паттерн "фабрика":

from django.forms import Textarea
Form = modelform_factory(Book, form=BookForm,
             widgets={"title": Textarea()})

Валидация datetime в классе формы

import datetime

def clean_datetime(self):

    d = self.cleaned_data['datetime']
    # для корректного сравнения и избежании ошибки, убираем временную зону
    d = d.replace(tzinfo=None)
    now = datetime.datetime.now()

    if d < now:
        raise ValidationError('Недопустимое значение! Дата события не может быть уже прошедшей.')
    if d > now + datetime.timedelta(days=365):
        raise ValidationError('Недопустимое значение! Дата планируемого события не может быть задана больше, '
                              'чем на год вперёд от настоящего времени.')
    return d

AJAX

Работа с redis

# Зайти в redis:
redis-cli
# Выбрать базу, отличную от 0
select 2
# Посмотреть все сохранённые ключи:
keys *
# Delete all data in cache:
flushall
# Show size of data:
size
# Проверить работу redis и базы:
ping # pong

Декораторы для View

Про декораторы в Python:

Пример кастомного декоратора, проверяющего, что запрос совершён с помощью ajax и метода post:

from django.core.exceptions import PermissionDenied

def allow_post_ajax(func):
    """
    Декоратор, разрешающий действия только c помощью ajax и post-запросов
    :param func:
    :return: func
    """
    def wrap(request, *args, **kwargs):
        if request.is_ajax() and request.method == 'POST':
            return func(request, *args, **kwargs)
        else:
            raise PermissionDenied

   return wrap

Кастомный декоратор с передачей аргументов в функцию:

def wrap_in_a(tag):
   """
   Wrap the result of a function in a `tag` HTML tag.
   """
   def _dec(func):
       def _new_func(*args, **kwargs):
           return "<%s>%s</%s>" % (tag, func(*args, **kwargs), tag)
       return _new_func
   return _dec

@wrap_in_a('div')
@login_required
def my_name(request):
    return request.user.first_name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment