]> git.ozlabs.org Git - patchwork/blob - apps/patchwork/forms.py
Use self.fields[field] rather than self.field when iterating form fields
[patchwork] / apps / patchwork / forms.py
1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
3 #
4 # This file is part of the Patchwork package.
5 #
6 # Patchwork is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # Patchwork is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Patchwork; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20
21 from django.contrib.auth.models import User
22 from django import forms
23
24 from patchwork.models import Patch, State, Bundle, UserProfile
25 from registration.forms import RegistrationFormUniqueEmail
26 from registration.models import RegistrationProfile
27
28 class RegistrationForm(RegistrationFormUniqueEmail):
29     first_name = forms.CharField(max_length = 30, required = False)
30     last_name = forms.CharField(max_length = 30, required = False)
31     username = forms.CharField(max_length=30, label=u'Username')
32     email = forms.EmailField(max_length=100, label=u'Email address')
33     password = forms.CharField(widget=forms.PasswordInput(),
34                                 label='Password')
35     password1 = forms.BooleanField(required = False)
36     password2 = forms.BooleanField(required = False)
37
38     def save(self, profile_callback = None):
39         user = RegistrationProfile.objects.create_inactive_user( \
40                 username = self.cleaned_data['username'],
41                 password = self.cleaned_data['password'],
42                 email = self.cleaned_data['email'],
43                 profile_callback = profile_callback)
44         user.first_name = self.cleaned_data.get('first_name', '')
45         user.last_name = self.cleaned_data.get('last_name', '')
46         user.save()
47         return user
48
49     def clean(self):
50         return self.cleaned_data
51
52 class LoginForm(forms.Form):
53     username = forms.CharField(max_length = 30)
54     password = forms.CharField(widget = forms.PasswordInput)
55
56 class BundleForm(forms.ModelForm):
57     class Meta:
58         model = Bundle
59         fields = ['name', 'public']
60
61 class CreateBundleForm(forms.ModelForm):
62     def __init__(self, *args, **kwargs):
63         super(CreateBundleForm, self).__init__(*args, **kwargs)
64
65     class Meta:
66         model = Bundle
67         fields = ['name']
68
69     def clean_name(self):
70         name = self.cleaned_data['name']
71         count = Bundle.objects.filter(owner = self.instance.owner, \
72                 name = name).count()
73         if count > 0:
74             raise forms.ValidationError('A bundle called %s already exists' \
75                     % name)
76         return name
77
78 class DelegateField(forms.ModelChoiceField):
79     def __init__(self, project, *args, **kwargs):
80         queryset = User.objects.filter(userprofile__in = \
81                 UserProfile.objects \
82                         .filter(maintainer_projects = project) \
83                         .values('pk').query)
84         super(DelegateField, self).__init__(queryset, *args, **kwargs)
85
86
87 class PatchForm(forms.ModelForm):
88     def __init__(self, instance = None, project = None, *args, **kwargs):
89         if (not project) and instance:
90             project = instance.project
91         if not project:
92             raise Exception("meep")
93         super(PatchForm, self).__init__(instance = instance, *args, **kwargs)
94         self.fields['delegate'] = DelegateField(project, required = False)
95
96     class Meta:
97         model = Patch
98         fields = ['state', 'archived', 'delegate']
99
100 class UserProfileForm(forms.ModelForm):
101     class Meta:
102         model = UserProfile
103         fields = ['primary_project', 'patches_per_page']
104
105 class OptionalDelegateField(DelegateField):
106     no_change_choice = ('*', 'no change')
107
108     def __init__(self, no_change_choice = None, *args, **kwargs):
109         self.filter = None
110         if (no_change_choice):
111             self.no_change_choice = no_change_choice
112         super(OptionalDelegateField, self). \
113             __init__(initial = self.no_change_choice[0], *args, **kwargs)
114
115     def _get_choices(self):
116         choices = list(
117                 super(OptionalDelegateField, self)._get_choices())
118         choices.append(self.no_change_choice)
119         return choices
120
121     choices = property(_get_choices, forms.ChoiceField._set_choices)
122
123     def is_no_change(self, value):
124         return value == self.no_change_choice[0]
125
126     def clean(self, value):
127         if value == self.no_change_choice[0]:
128             return value
129         return super(OptionalDelegateField, self).clean(value)
130
131 class OptionalModelChoiceField(forms.ModelChoiceField):
132     no_change_choice = ('*', 'no change')
133
134     def __init__(self, no_change_choice = None, *args, **kwargs):
135         self.filter = None
136         if (no_change_choice):
137             self.no_change_choice = no_change_choice
138         super(OptionalModelChoiceField, self). \
139             __init__(initial = self.no_change_choice[0], *args, **kwargs)
140
141     def _get_choices(self):
142         choices = list(
143                 super(OptionalModelChoiceField, self)._get_choices())
144         choices.append(self.no_change_choice)
145         return choices
146
147     choices = property(_get_choices, forms.ChoiceField._set_choices)
148
149     def is_no_change(self, value):
150         return value == self.no_change_choice[0]
151
152     def clean(self, value):
153         if value == self.no_change_choice[0]:
154             return value
155         return super(OptionalModelChoiceField, self).clean(value)
156
157 class MultipleBooleanField(forms.ChoiceField):
158     no_change_choice = ('*', 'no change')
159     def __init__(self, *args, **kwargs):
160         super(MultipleBooleanField, self).__init__(*args, **kwargs)
161         self.choices = [self.no_change_choice] + \
162                 [(True, 'Archived'), (False, 'Unarchived')]
163
164     def is_no_change(self, value):
165         return value == self.no_change_choice[0]
166
167 class MultiplePatchForm(PatchForm):
168     state = OptionalModelChoiceField(queryset = State.objects.all())
169     archived = MultipleBooleanField()
170
171     def __init__(self, project, *args, **kwargs):
172         super(MultiplePatchForm, self).__init__(project = project,
173                 *args, **kwargs)
174         self.fields['delegate'] = OptionalDelegateField(project = project,
175                 required = False)
176
177     def save(self, instance, commit = True):
178         opts = instance.__class__._meta
179         if self.errors:
180             raise ValueError("The %s could not be changed because the data "
181                     "didn't validate." % opts.object_name)
182         data = self.cleaned_data
183         # remove 'no change fields' from the data
184         for f in opts.fields:
185             if not f.name in data:
186                 continue
187
188             field = self.fields.get(f.name, None)
189             if not field:
190                 continue
191
192             if field.is_no_change(data[f.name]):
193                 del data[f.name]
194
195         return forms.save_instance(self, instance,
196                 self._meta.fields, 'changed', commit)
197
198 class UserPersonLinkForm(forms.Form):
199     email = forms.EmailField(max_length = 200)