29 августа 2013 г.

django upload_to windows 123 bad chars

Использовал свою реализацию upload_to-метода для формирования пути сохранения файлов в FileField-поле модели на основании заголовка сущности (чтобы файлики сохранялись в подпапки контрагентов). При разработке под linux всё было отлично, но в продакшене на одной windows-машине периодически валилась загрузка файлов
File "C:\python27\lib\site-packages\django\core\files\storage.py", line 168, in _save
    os.makedirs(directory)
  File "C:\python27\lib\os.py", line 150, in makedirs
    makedirs(head, mode)
  File "C:\python27\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 123] Синтаксическая ошибка в имени файла,: u'C:\\inetpub\\wwwroot\\ZooDjangoProject\\media\\file\\\blabla "blabla"'
Выяснилось, что дело в кавычках в имени файлов, который есть запретный символ в винде. Пришлось вспомнить и остальные ограничения, после чего родилось прижившееся экспресс-решение.
def removebadchars(value):
    for c in r'\/:*?"<>|':
        value = value.replace(c, '')
    return value
...
filename = removebadchars(filename)

27 августа 2013 г.

Версия приложения через makefile прямиком из git

Так как код я держу в той или иной VCS (последнее время чаще всего в git) я подумал, что было бы круто версию приложений брать из репозитория, а конкретно — из тегов. Для небольших утилит особенно удобно. Некоторые похожие решения из интернета натолкнули меня на такое решение. Всё довольно просто, пример для обычного gnu-makefile и исходника на Си.

26 августа 2013 г.

django admin запрет редактирования модели

Запрещение в админке django редактирования какой-либо сущности. В моём случае это оповещения об оплатах платёжной системы. В ModelAdmin есть методы has_add_permission, has_change_permission, has_delete_permission с очевидным предназначением. Правда, если все они вернут в каком-то случае False, то модель вообще не отобразится в списке сущностей админки и по прямой ссылке тоже не будет работать. Так что все поля вместо has_change_permission надо сделать readonly.
class SuccessNotificationAdmin(admin.ModelAdmin):
    ...
    readonly_fields = ('order', 'sum', )

    def has_add_permission(self, request):
        return False

    #def has_change_permission(self, request, obj=None):
    #    return False

    def has_delete_permission(self, request, obj=None):
        return False

admin.site.register(SuccessNotification, SuccessNotificationAdmin)

25 августа 2013 г.

django favicon.ico robots.txt

Есть некоторая проблема с такого рода файлами в django. Они предполагаются находящимися в корне, а статика как правило раздаётся из «подкаталога» (например, /static/). Да, в случае favicon.ico его можно указать в meta-тегах страницы, но в некоторых случаях, например, при отдаче 500 ошибки или в любом другом случае без учёта корневого шаблона с meta-тегами, некоторые браузеры всё равно запрашивают /favicon.ico из корня, напрягая логи WARN-ошибками 404. Потому удобно в urls.py перенаправлять редиректом на реальные расположения файлов.
url(r'^favicon\.ico$', RedirectView.as_view(url=settings.STATIC_URL + 'images/favicon.ico')),
url(r'^robots\.txt$', RedirectView.as_view(url=settings.STATIC_URL + 'robots.txt')),
В случае robots.txt можно отдавать как шаблон, если удобнее (можно и mime задать, начиная с 1.5, емнип)
url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
Для старых версий django это будут процедурные вьюшки redirect_to и direct_to_template соответственно, приводить код тут не буду за бессмысленностью.