File: fields.py

package info (click to toggle)
drf-haystack 1.8.4-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 584 kB
  • sloc: python: 2,594; makefile: 147
file content (114 lines) | stat: -rw-r--r-- 3,437 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# -*- coding: utf-8 -*-

from __future__ import absolute_import, unicode_literals

from django.utils import six
from rest_framework import fields


class DRFHaystackFieldMixin(object):
    prefix_field_names = False

    def __init__(self, **kwargs):
        self.prefix_field_names = kwargs.pop('prefix_field_names', False)
        super(DRFHaystackFieldMixin, self).__init__(**kwargs)

    def bind(self, field_name, parent):
        """
        Initializes the field name and parent for the field instance.
        Called when a field is added to the parent serializer instance.
        Taken from DRF and modified to support drf_haystack multiple index
        functionality.
        """

        # In order to enforce a consistent style, we error if a redundant
        # 'source' argument has been used. For example:
        # my_field = serializer.CharField(source='my_field')
        assert self.source != field_name, (
            "It is redundant to specify `source='%s'` on field '%s' in "
            "serializer '%s', because it is the same as the field name. "
            "Remove the `source` keyword argument." %
            (field_name, self.__class__.__name__, parent.__class__.__name__)
        )

        self.field_name = field_name
        self.parent = parent

        # `self.label` should default to being based on the field name.
        if self.label is None:
            self.label = field_name.replace('_', ' ').capitalize()

        # self.source should default to being the same as the field name.
        if self.source is None:
            self.source = self.convert_field_name(field_name)

        # self.source_attrs is a list of attributes that need to be looked up
        # when serializing the instance, or populating the validated data.
        if self.source == '*':
            self.source_attrs = []
        else:
            self.source_attrs = self.source.split('.')

    def convert_field_name(self, field_name):
        if not self.prefix_field_names:
            return field_name
        return field_name.split("__")[-1]


class HaystackBooleanField(DRFHaystackFieldMixin, fields.BooleanField):
    pass


class HaystackCharField(DRFHaystackFieldMixin, fields.CharField):
    pass


class HaystackDateField(DRFHaystackFieldMixin, fields.DateField):
    pass


class HaystackDateTimeField(DRFHaystackFieldMixin, fields.DateTimeField):
    pass


class HaystackDecimalField(DRFHaystackFieldMixin, fields.DecimalField):
    pass


class HaystackFloatField(DRFHaystackFieldMixin, fields.FloatField):
    pass


class HaystackIntegerField(DRFHaystackFieldMixin, fields.IntegerField):
    pass


class HaystackMultiValueField(DRFHaystackFieldMixin, fields.ListField):
    pass


class FacetDictField(fields.DictField):
    """
    A special DictField which passes the key attribute down to the children's
    ``to_representation()`` in order to let the serializer know what field they're
    currently processing.
    """

    def to_representation(self, value):
        return dict(
            [(six.text_type(key), self.child.to_representation(key, val))
             for key, val in value.items()
             ]
        )


class FacetListField(fields.ListField):
    """
    The ``FacetListField`` just pass along the key derived from
    ``FacetDictField``.
    """

    def to_representation(self, key, data):
        return [self.child.to_representation(key, item) for item in data]