forms.py 5.58 KB
Newer Older
1
2
# standard library imports
from __future__ import absolute_import, print_function
3
# core django imports
4
from django import forms
5
6
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
Daniel W Bond's avatar
Daniel W Bond committed
7
8
from django.utils.encoding import force_text
from django.core.exceptions import ValidationError
9
from django.utils.translation import ugettext as _
10
# third party imports
11
from crispy_forms.helper import FormHelper
Daniel W Bond's avatar
Daniel W Bond committed
12
13
from crispy_forms.layout import Submit, Layout
from crispy_forms.bootstrap import PrependedText, AppendedText
Daniel W Bond's avatar
Daniel W Bond committed
14
from multiselectfield import MultiSelectFormField
15
# imports from your apps
16
17
18
19
20
21
22
23
from .models import Student, Major
from housing.models import Building, Floor, Room


class SelectRoomWidget(forms.widgets.Select):

    template_name = 'room_select_widget.html'

24
    def __init__(self, user=None, attrs=None, rooms=None, floors=None, buildings=None, neighborhoods=None):
25
26
27
28
        super(SelectRoomWidget, self).__init__(attrs)
        # attrs to be implemented later (allows specifying css class, for example)
        if attrs:
            print("Sorry about that, but we're currently ignoring your fancy attrs.")
29
        # should probably type check the other fields too
30
31
        if rooms is None:
            self.rooms = Room.objects.all()
32
33
34
35
36
37
38
39
40
41
42
        else:
            if not all(isinstance(thing, Room) for thing in rooms):
                raise TypeError("Rooms in a SelectRoomWidget must all be Rooms!")
        if floors is None:
            self.floors = Floor.objects.all()
        if buildings is None:
            self.buildings = Building.objects.all()
        if neighborhoods is None:
            self.neighborhoods = Building.NEIGHBOURHOOD_CHOICES

    def render(self, name, value, attrs=None):
43
        context = {
44
45
46
            'neighborhoods': self.neighborhoods,
            'buildings': self.buildings,
            'floors': self.floors,
47
            'rooms': self.rooms,
48
        }
49
50
        if self.user is not None:
            context['user'] = self.user
51
        return mark_safe(render_to_string(self.template_name, context))
52

Daniel W Bond's avatar
Daniel W Bond committed
53

Daniel W Bond's avatar
Daniel W Bond committed
54
55
56
class SelectRoomField(forms.models.ModelChoiceField):
    widget = SelectRoomWidget

57
58
#    should raise error if user hasn't actually selected room, made it to end of selectors
#    def clean(self, value):
Daniel W Bond's avatar
Daniel W Bond committed
59

60
class StudentUpdateForm(forms.Form):
61

62
63
    first_name = forms.CharField(label='First Name', required=False)
    last_name = forms.CharField(label='Last Name', required=False)
64
    gender = MultiSelectFormField(choices=Student.GENDER_CHOICES,
65
66
                                  label='Gender Identity (please choose all that apply)',
                                  required=False)
67
68
    show_gender = forms.BooleanField(label='Show your gender on your profile?',
                                     required=False)
69

70
    room = SelectRoomField(queryset=Room.objects.all(), label='', required=False)
71

72
    privacy = forms.ChoiceField(choices=Student.PRIVACY_CHOICES)
73
74
    major = forms.ModelChoiceField(queryset=Major.objects.all(), required=False,
                                   label='Major (select one)',)
75
    graduating_year = forms.IntegerField(label='Graduating Year')
76

Daniel W Bond's avatar
Daniel W Bond committed
77

78
79
80
81
82
83
84
85
86
    def clean(self):
        cleaned_data = super(StudentUpdateForm, self).clean()
        form_room = cleaned_data.get('room')
        students_in_room = Student.objects.filter(room=form_room).count()
        #print(students_in_room)
        # like in bookshare, I have no idea why the form errors don't display.
        if students_in_room > 12:
            raise ValidationError(_('Too many students in room (%d).' % students_in_room), code='invalid')

Daniel W Bond's avatar
Daniel W Bond committed
87
    def is_valid(self):
88
89
90
91
        # errors are not printed in form.as_p?
        #print("In is_valid.")
        #print(self.is_bound, 'is bound')
        #print(self.errors, type(self.errors), 'errors')
Daniel W Bond's avatar
Daniel W Bond committed
92
        valid = super(StudentUpdateForm, self).is_valid()
93
        #print(valid)
Daniel W Bond's avatar
Daniel W Bond committed
94
95
        return valid

Daniel W Bond's avatar
Daniel W Bond committed
96
97
class WelcomeNameForm(forms.Form):

98
99
    first_name = forms.CharField(label='First Name', required=False)
    last_name = forms.CharField(label='Last Name', required=False)
100
    gender = MultiSelectFormField(choices=Student.GENDER_CHOICES,
101
102
103
104
                                  label='Gender Identity (please choose all that apply)',
                                  required=False)
    show_gender = forms.BooleanField(label='Show your gender on your profile?',
                                     required=False)
105
106
107
108


class WelcomePrivacyForm(forms.ModelForm):

Daniel W Bond's avatar
Daniel W Bond committed
109
110
    def __init__(self, *args, **kwargs):
        super(WelcomePrivacyForm, self).__init__(*args, **kwargs)
111
        if self.instance.recent_changes() > 2:
Daniel W Bond's avatar
Daniel W Bond committed
112
            self.fields['room'].widget = forms.widgets.HiddenInput()
113
114
115
        else:
            self.fields['room'] = SelectRoomField(queryset=Room.objects.all(),
                                                  label='', required=False)
Daniel W Bond's avatar
Daniel W Bond committed
116

117
118
119
120
121
122
123
124
125
    def clean(self):
        cleaned_data = super(WelcomePrivacyForm, self).clean()
        form_room = cleaned_data.get('room')
        students_in_room = Student.objects.filter(room=form_room).count()
        #print(students_in_room)
        # like in bookshare, I have no idea why the form errors don't display.
        if students_in_room > 12:
            raise ValidationError(_('Too many students in room (%d).' % students_in_room), code='invalid')

126
127
    class Meta:
        model = Student
Daniel W Bond's avatar
Daniel W Bond committed
128
        fields = ('room', 'privacy', )
129
130
131
132


class WelcomeSocialForm(forms.ModelForm):

Daniel W Bond's avatar
Daniel W Bond committed
133
134
135
136
    def __init__(self, *args, **kwargs):
        super(WelcomeSocialForm, self).__init__(*args, **kwargs)
        self.fields['completedSocial'].widget = forms.widgets.HiddenInput()

137
138
    class Meta:
        model = Student
Daniel W Bond's avatar
Daniel W Bond committed
139
        fields = ('completedSocial', )