source: djangobb_forum/fields.py @ 434:21cb6ef7649d

Last change on this file since 434:21cb6ef7649d was 434:21cb6ef7649d, checked in by slav0nic <slav0nic0@…>, 14 months ago

fix DeprecationWarning? for django 1.4; update projects

File size: 3.6 KB
Line 
1"""
2Details about AutoOneToOneField:
3    http://softwaremaniacs.org/blog/2007/03/07/auto-one-to-one-field/
4"""
5try:
6    from cStringIO import StringIO
7except ImportError:
8    from StringIO import StringIO
9import random
10from hashlib import sha1
11
12from django.db.models import OneToOneField
13from django.db.models.fields.related import SingleRelatedObjectDescriptor
14from django.db import models
15from django.core.files.uploadedfile import SimpleUploadedFile
16from django.core.serializers.json import DjangoJSONEncoder
17from django.utils import simplejson as json
18from django.conf import settings
19
20
21class AutoSingleRelatedObjectDescriptor(SingleRelatedObjectDescriptor):
22    def __get__(self, instance, instance_type=None):
23        try:
24            return super(AutoSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)
25        except self.related.model.DoesNotExist:
26            obj = self.related.model(**{self.related.field.name: instance})
27            obj.save()
28            return obj
29
30
31class AutoOneToOneField(OneToOneField):
32    """
33    OneToOneField creates dependent object on first request from parent object
34    if dependent oject has not created yet.
35    """
36
37    def contribute_to_related_class(self, cls, related):
38        setattr(cls, related.get_accessor_name(), AutoSingleRelatedObjectDescriptor(related))
39        #if not cls._meta.one_to_one_field:
40        #    cls._meta.one_to_one_field = self
41
42
43class ExtendedImageField(models.ImageField):
44    """
45    Extended ImageField that can resize image before saving it.
46    """
47
48    def __init__(self, *args, **kwargs):
49        self.width = kwargs.pop('width', None)
50        self.height = kwargs.pop('height', None)
51        super(ExtendedImageField, self).__init__(*args, **kwargs)
52
53    def save_form_data(self, instance, data):
54        if data and self.width and self.height:
55            content = self.resize_image(data.read(), width=self.width, height=self.height)
56            salt = sha1(str(random.random())).hexdigest()[:5]
57            fname =  sha1(salt + settings.SECRET_KEY).hexdigest() + '.png'
58            data = SimpleUploadedFile(fname, content, data.content_type)
59        super(ExtendedImageField, self).save_form_data(instance, data)
60
61    def resize_image(self, rawdata, width, height):
62        """
63        Resize image to fit it into (width, height) box.
64        """
65        try:
66            import Image
67        except ImportError:
68            from PIL import Image
69        image = Image.open(StringIO(rawdata))
70        oldw, oldh = image.size
71        if oldw >= oldh:
72            x = int(round((oldw - oldh) / 2.0))
73            image = image.crop((x, 0, (x + oldh) - 1, oldh - 1))
74        else:
75            y = int(round((oldh - oldw) / 2.0))
76            image = image.crop((0, y, oldw - 1, (y + oldw) - 1))
77        image = image.resize((width, height), resample=Image.ANTIALIAS)
78
79
80        string = StringIO()
81        image.save(string, format='PNG')
82        return string.getvalue()
83
84
85class JSONField(models.TextField):
86    """
87    JSONField is a generic textfield that neatly serializes/unserializes
88    JSON objects seamlessly.
89    Django snippet #1478
90    """
91
92    __metaclass__ = models.SubfieldBase
93
94    def to_python(self, value):
95        if value == "":
96            return None
97
98        try:
99            if isinstance(value, basestring):
100                return json.loads(value)
101        except ValueError:
102            pass
103        return value
104
105    def get_prep_value(self, value):
106        if value == "":
107            return None
108        if isinstance(value, dict):
109            value = json.dumps(value, cls=DjangoJSONEncoder)
110        return super(JSONField, self).get_prep_value(value)
Note: See TracBrowser for help on using the repository browser.