Tag: Django

Bad Request (400) в django на поле ForeignKey

Возникла ошибка Bad Request (400) на вот таком примере (не буду приводить всю модель, только то что важно):

models.py

class Institution(models.Model):
    '''
    Образовательно учреждение
    '''
    name = models.CharField(max_length=255, verbose_name=u'Название')
    address = models.CharField(max_length=255, verbose_name=u'Адрес')

class CustomUser(models.Model):
    '''
    Расширяем пользовательскую модель под педагогов
    '''
    user = models.OneToOneField(User)
    phone = models.CharField(max_length=11, blank=True, null=True, verbose_name=u'Телефон')
    middle_name = models.CharField(max_length=100, blank=True, verbose_name=u'Отчетсво')
    institution = models.ForeignKey(Institution, blank=True, null=True, verbose_name=u'Учереждение')

admin.py

class CustomUserInline(admin.StackedInline):
    model = CustomUser
    can_delete = False

class CustomUserAdmin(UserAdmin):
    list_display = ('username', 'email', 'last_name', 'first_name')
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)

На официальном сайте есть тикет по этому поводу https://code.djangoproject.com/ticket/23552 и следовательно лечим добавлением класса CustomUserAdmin

Новый admin.py

class CustomUserInline(admin.StackedInline):
    model = CustomUser
    can_delete = False

class CustomUserAdmin(admin.ModelAdmin):
    def get_inline_instances(self, request, obj=None):
        return [inline(self.model, self.admin_site) for inline in [CustomUserInline]]
admin.site.register(CustomUser, CustomUserAdmin)

class CustomUserAdmin(UserAdmin):
    list_display = ('username', 'email', 'last_name', 'first_name')
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)

django.db.utils.IntegrityError: (1215, ‘Cannot add foreign key constraint’)

Получил в Django при выполнении миграции вот такую ошибку

django.db.utils.IntegrityError: (1215, ‘Cannot add foreign key constraint’)

связано это с тем что в базе смесь таблиц InnoDB и MyISAM. Лечим просто -> переводим все таблицы в InnoDB.

Редирект в urls.py (Django, RedirectView)

Порой нужно не создавая вьюшки прямо на входе перенаправить с запрошенного адреса на другой. Пример:

from django.conf.urls import patterns, url
from django.views.generic.base import RedirectView

urlpatterns = patterns('',
    url(r'^go-to-url/$', RedirectView.as_view(url='http://developtolive.com'), name='go-to-url'),
)

Выводит записи журнала действий пользователей в административной части в Django

Задача: вывести записи журнала действий пользователей в административной части в Django
Решение: Сама модель логирования в Django вот такая LogEntry и находится в django.contrib.admin.models. Все что нудно сделать это обычным способом вывести модель в админке.
В файле admin.py

# -*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib.admin.models import LogEntry

class LogEntryAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'action_time', 'user', 'content_type', 'object_id', 'object_repr', 'action_flag', 'change_message')
    list_filter = ('content_type',)
    search_fields = ['user__username',]
    date_hierarchy = 'action_time'
admin.site.register(LogEntry, LogEntryAdmin)

Удаление файла при удалении записи в модели в Django

Сигнал который удаляет физически файл с диска при удалении объекта в модели.

from django.db.models.signals import post_delete
from django.dispatch import receiver

@receiver(post_delete, sender=Photo)
def photo_post_delete_handler(sender, **kwargs):
    photo = kwargs['instance']
    storage, path = photo.original_image.storage, photo.original_image.path
    storage.delete(path)

Django No module named _imagingft

Получил такую ошибку при использовании пакета django-simple-captcha на своем Mac OS 1.7

Request Method: 	GET
Request URL: 	http://127.0.0.1:8000/captcha/image/1d5040700009449016d09eb56c9c55e11560844d/
Django Version: 	1.4.3
Exception Type: 	ImportError
Exception Value: 	

The _imagingft C module is not installed

Exception Location: 	/Library/Python/2.7/site-packages/PIL-1.1.7-py2.7-macosx-10.7-intel.egg/ImageFont.py in __getattr__, line 34
Python Executable: 	/usr/bin/python

Решается это следующим образом

sudo pip uninstall PIL
sudo rm -rf /Library/Python/2.7/site-packages/PIL*

sudo ln -s /usr/X11/include/freetype2 /usr/include/ 
sudo ln -s /usr/X11/include/ft2build.h /usr/include/ 
sudo ln -s /usr/X11/lib/libfreetype.6.dylib /local/lib/ 
sudo ln -s /usr/X11/lib/libfreetype.6.dylib /local/lib/libfreetype.dylib 

sudo pip install PIL

MySQLdb на Mac OS получил ошибку Library not loaded: libmysqlclient.18.dylib

После установки пакета MySQLdb и обращения к ней

In [1]: import MySQLdb

получаю ошибку

ImportError: dlopen(/Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.7-intel.egg/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
  Referenced from: /Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.7-intel.egg/_mysql.so
  Reason: image not found

Лечиться это просто, через консоль создайте сылку

sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

The _imaging C module is not installed windows

На одной из машин под windows в PIL на django проекте поймал ошибку

The _imaging C module is not installed

На одном из ресурсов мне посоветовали воспользоваться репозитарием на сайте Калифорнийского университета. После установки пакета PIL из их репозитария Unofficial Windows Binaries for Python Extension Packages и все заработало.

Наложение водяного знака в Django

Как я решил вопрос наложения водяного знака на изображение за 2 минуты.
Написал некую функцию которая и реализует наложение водяного знака с помощью модуля PIL:

import Image, ImageEnhance

def add_watermark(image, watermark, opacity=1, wm_interval=0):
    assert opacity >= 0 and opacity <= 1
    if opacity < 1:
        if watermark.mode != 'RGBA':
            self.watermark = watermark.convert('RGBA')
        else:
            watermark = watermark.copy()
        alpha = watermark.split()[3]
        alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
        watermark.putalpha(alpha)

    layer = Image.new('RGBA', image.size, (0,0,0,0))
    for y in range(0, image.size[1], watermark.size[1]+wm_interval):
        for x in range(0, image.size[0], watermark.size[0]+wm_interval):
            layer.paste(watermark, (x, y))
    return Image.composite(layer,  image,  layer)

В моделе есть поле image, вот на него мы и накладываем водяной знак при любом сохранении объекта (это плохо — так не делайте, хотя бы по тому, что при каждом сохранении на изображение наложится повторно водяной знак, я это написал для наглядности). Вот этот сигнал и палит сохранение модели:

def prev_image(sender, instance, created, **kwargs):
    # Открываем водяной знак
    path_watermark = settings.STATIC_ROOT + '/watermark/logo.png'
    watermark_open = Image.open(path_watermark, 'r')

    # Открываем текущее изобразение изображение
    img_path = '/home/isite/data/django-apps/energy' + instance.image.url
    img_open = Image.open(img_path, 'r')

    # Накладываем водяной знак
    add_watermark(img_open, watermark_open, 0.3, 50).save(img_path)

signals.post_save.connect(prev_image, sender=Product)

Django Email Attachment

Отправляем письма в Django с прикрепленным файлом

------forms.py----------
from django import forms

class EmailForm(forms.Form):
    email = forms.EmailField()
    subject = forms.CharField(max_length=100)
    attach = forms.Field(widget = forms.FileInput)
    message = forms.CharField(widget = forms.Textarea)
-------views.py--------------

def send_email(request):
    if request.method != 'POST':
        form = EmailForm()
        return render_to_response('admin/Email.html', {'email_form': form})
	
    form = EmailForm(request.POST, request.FILES)	
    if form.is_valid():
        subject = form.cleaned_data['subject']
        message = form.cleaned_data['message']
        email = form.cleaned_data['email']
        attach = request.FILES['attach']
        try:
            mail = EmailMessage(subject, message, settings.EMAIL_HOST_USER, [email])
            mail.attach(attach.name, attach.read(), attach.content_type)
            mail.send()
            return render_to_response('admin/Email.html', {'message': 'Sent email to %s'%email})
       except:
           return render_to_response('admin/Error.html', {'message': 'Either the attachment is too  big or corrupt'})
       return render_to_response('admin/Email.html', {'message': 'Unable to send email. Please try again later'})
---------template------

{% extends "admin/base_site.html" %}

{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css{% endblock %}
{% block bodyclass %}dashboard{% endblock %}
{% block coltype %}colMS{% endblock %}

{% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Send Email</div>{% endblock %}{% endif %}

{% block content %}
{{message}}
{% if email_form %}
<form method="POST" action ="." enctype="multipart/form-data">
<br></br>
{{email_form.as_p}}

<label> </label><label> </label><label> </label>
<input type ="submit"  name = "send" value = "Send"/>
</form>
{% endif %}
{% endblock content %}