Projet

Général

Profil

0001-add-a-binary-file-field-66533.patch

Benjamin Dauvergne, 03 août 2022 01:05

Télécharger (4,76 ko)

Voir les différences:

Subject: [PATCH 1/2] add a binary file field (#66533)

 passerelle/utils/forms.py  | 76 ++++++++++++++++++++++++++++++++++++++
 passerelle/utils/models.py | 33 +++++++++++++++++
 2 files changed, 109 insertions(+)
 create mode 100644 passerelle/utils/forms.py
 create mode 100644 passerelle/utils/models.py
passerelle/utils/forms.py
1
# passerelle - uniform access to multiple data sources and services
2
# Copyright (C) 2022  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django import forms
18

  
19

  
20
class BinaryFileInput(forms.ClearableFileInput):
21
    def is_initial(self, value):
22
        """
23
        Return whether value is considered to be initial value.
24
        """
25
        return bool(value)
26

  
27
    def format_value(self, value):
28
        """Format the size of the value in the db.
29

  
30
        We can't render it's name or url, but we'd like to give some information
31
        as to wether this file is not empty/corrupt.
32
        """
33
        if self.is_initial(value):
34
            return f'{len(value)} bytes'
35

  
36
    def value_from_datadict(self, data, files, name):
37
        """Return the file contents so they can be put in the db."""
38
        upload = super().value_from_datadict(data, files, name)
39
        if upload:
40
            return upload.read()
41
        return upload
42

  
43

  
44
class BinaryFileField(forms.FileField):
45
    widget = BinaryFileInput
46

  
47
    def __init__(self, *, max_length=None, **kwargs):
48
        self.max_length = max_length
49
        super().__init__(**kwargs)
50

  
51
    def to_python(self, value):
52
        return value
53

  
54
    def clean(self, data, initial=None):
55
        # False means the field value should be cleared; further validation is
56
        # not needed.
57
        if data is False:
58
            if not self.required:
59
                return None
60
            # If the field is required, clearing is not possible (the widget
61
            # shouldn't return False data in that case anyway). False is not
62
            # in self.empty_value; if a False value makes it this far
63
            # it should be validated from here on out as None (so it will be
64
            # caught by the required check).
65
            data = None
66
        if not data and initial:
67
            return initial
68
        return super(forms.FileField, self).clean(data)
69

  
70
    def bound_data(self, data, initial):
71
        if data is None:
72
            return initial
73
        return data
74

  
75
    def has_changed(self, initial, data):
76
        return not self.disabled and data is not None
passerelle/utils/models.py
1
# passerelle - uniform access to multiple data sources and services
2
# Copyright (C) 2022  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django.db import models
18

  
19

  
20
class BinaryFileField(models.BinaryField):
21
    def __init__(self, *args, **kwargs):
22
        kwargs.setdefault('editable', True)
23
        super().__init__(*args, **kwargs)
24

  
25
    def formfield(self, **kwargs):
26
        from .forms import BinaryFileField
27

  
28
        return super().formfield(
29
            **{
30
                'form_class': BinaryFileField,
31
                **kwargs,
32
            }
33
        )
0
-