|
1 | 1 | from __future__ import absolute_import, unicode_literals |
2 | 2 |
|
3 | | -import inspect |
4 | 3 | from django.apps import AppConfig as DjangoAppConfig |
5 | | -import django.forms.models |
| 4 | +import cassandra.cqlengine.columns |
6 | 5 |
|
7 | 6 |
|
8 | | -def construct_instance(form, instance, fields=None, exclude=None): |
| 7 | +class CallableBool: |
9 | 8 | """ |
10 | | - Taken from django.forms.models.construct_instance |
11 | | - altered to support cqlengine models (see field_has_default logic) |
| 9 | + An boolean-like object that is also callable for backwards compatibility. |
12 | 10 | """ |
13 | | - from django.db import models |
14 | | - opts = instance._meta |
15 | | - |
16 | | - cleaned_data = form.cleaned_data |
17 | | - file_field_list = [] |
18 | | - for f in opts.fields: |
19 | | - if not f.editable or isinstance(f, models.AutoField) \ |
20 | | - or f.name not in cleaned_data: |
21 | | - continue |
22 | | - if fields is not None and f.name not in fields: |
23 | | - continue |
24 | | - if exclude and f.name in exclude: |
25 | | - continue |
26 | | - # Leave defaults for fields that aren't in POST data, except for |
27 | | - # checkbox inputs because they don't appear in POST data if not checked |
28 | | - |
29 | | - # cqlengine support logic start |
30 | | - if inspect.ismethod(f.has_default): |
31 | | - # django model |
32 | | - field_has_default = f.has_default() |
33 | | - else: |
34 | | - # cqlengine model |
35 | | - field_has_default = f.has_default |
36 | | - # cqlengine support logic end |
37 | | - |
38 | | - if (field_has_default and form.add_prefix(f.name) not in form.data and |
39 | | - not getattr(form[f.name].field.widget, |
40 | | - 'dont_use_model_field_default_for_empty_data', False)): |
41 | | - continue |
42 | | - # Defer saving file-type fields until after the other fields, so a |
43 | | - # callable upload_to can use the values from other fields. |
44 | | - if isinstance(f, models.FileField): |
45 | | - file_field_list.append(f) |
46 | | - else: |
47 | | - f.save_form_data(instance, cleaned_data[f.name]) |
48 | | - |
49 | | - for f in file_field_list: |
50 | | - f.save_form_data(instance, cleaned_data[f.name]) |
51 | | - |
52 | | - return instance |
53 | | - |
54 | | -# patching so that Django ModelForms can work with cqlengine models |
55 | | -django.forms.models.construct_instance = construct_instance |
| 11 | + |
| 12 | + def __init__(self, value): |
| 13 | + self.value = value |
| 14 | + |
| 15 | + def __bool__(self): |
| 16 | + return self.value |
| 17 | + |
| 18 | + def __call__(self): |
| 19 | + return self.value |
| 20 | + |
| 21 | + def __nonzero__(self): # Python 2 compatibility |
| 22 | + return self.value |
| 23 | + |
| 24 | + def __repr__(self): |
| 25 | + return 'CallableBool(%r)' % self.value |
| 26 | + |
| 27 | + def __eq__(self, other): |
| 28 | + return self.value == other |
| 29 | + |
| 30 | + def __ne__(self, other): |
| 31 | + return self.value != other |
| 32 | + |
| 33 | + def __or__(self, other): |
| 34 | + return bool(self.value or other) |
| 35 | + |
| 36 | + def __hash__(self): |
| 37 | + return hash(self.value) |
| 38 | + |
| 39 | + |
| 40 | +def has_default(self): |
| 41 | + return CallableBool(self.default is not None) |
| 42 | + |
| 43 | +# monkey patch Column.has_default to be able to use function call too |
| 44 | +cassandra.cqlengine.columns.Column.has_default = property(has_default) |
56 | 45 |
|
57 | 46 |
|
58 | 47 | class AppConfig(DjangoAppConfig): |
|
0 commit comments