XFN Form Field

 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
from django import newforms as forms


XFN_FAMILY_RELS = ('child', 'kin', 'parent', 'sibling', 'spouse')
XFN_FRIENDSHIP_RELS = ('acquaintance', 'contact', 'friend')
XFN_GEOGRAPHICAL_RELS = ('co-resident', 'neighbor')
XFN_IDENTITY_RELS = ('me',)
XFN_PHYSICAL_RELS = ('met',)
XFN_PROFESSIONAL_RELS = ('colleague', 'co-worker')
XFN_ROMANTIC_RELS = ('crush', 'date', 'muse', 'sweetheart')
XFN_RELS = (
    XFN_FAMILY_RELS + XFN_FRIENDSHIP_RELS + XFN_GEOGRAPHICAL_RELS
    + XFN_IDENTITY_RELS + XFN_PHYSICAL_RELS + XFN_PROFESSIONAL_RELS
    + XFN_ROMANTIC_RELS
)


xfn_family_rels = set(XFN_FAMILY_RELS)
xfn_friendship_rels = set(XFN_FRIENDSHIP_RELS)
xfn_geographical_rels = set(XFN_GEOGRAPHICAL_RELS)
xfn_rels = set(XFN_RELS)


class XFNField(forms.Field):
    """Field to normalize and validate an XFN relationship.

    Strips extra whitespace, converts to lowercase and removes duplicates.

    Enforces exclusivity for the ``me`` value and allows at most one value from
    each of the family, friendship and geographical categories.

    Sorts values alphabetically -- not required, but *feels* right.

    http://gmpg.org/xfn/11

    """
    default_error_messages = {
        'family': u'XFN allows only one family value.',
        'friendship': u'XFN allows only one friendship value.',
        'invalid': u'Enter a valid XFN relationship.',
        'geographical': u'XFN allows only one geographical value.',
        'me': u'The "me" relationship can\'t be used with other values.',
        'required': u'Enter an XFN relationship.'
    }

    def clean(self, value):
        value = super(XFNField, self).clean(value)

        if value in forms.fields.EMPTY_VALUES:
            return u''

        rels = set(value.strip().lower().split())
        if len(rels - xfn_rels):
            raise forms.ValidationError(self.error_messages['invalid'])
        if len(rels & xfn_family_rels) > 1:
            raise forms.ValidationError(self.error_messages['family'])
        if len(rels & xfn_friendship_rels) > 1:
            raise forms.ValidationError(self.error_messages['friendship'])
        if len(rels & xfn_geographical_rels) > 1:
            raise forms.ValidationError(self.error_messages['geographical'])
        if 'me' in rels and len(rels) > 1:
            raise forms.ValidationError(self.error_messages['me'])

        return u' '.join(sorted(rels))

    def widget_attrs(self, widget):
        return {'class': 'xfn'}

More like this

  1. CustomChoiceField, Selectable label field version of ModelChoiceField by mauro 6 years, 1 month ago
  2. Tamper safe HiddenFields by alexmeisel 5 years, 5 months ago
  3. SectionedForm by marinho 5 years, 10 months ago
  4. Reorder fields directly in the ModelForm by HM 5 years, 11 months ago
  5. FieldsetForm by Ciantic 7 years ago

Comments

(Forgotten your password?)