Package omeroweb :: Package webadmin :: Module custom_forms
[hide private]
[frames] | no frames]

Source Code for Module omeroweb.webadmin.custom_forms

  1  #!/usr/bin/env python 
  2  #  
  3  #  
  4  #  
  5  # Copyright (c) 2008 University of Dundee.  
  6  #  
  7  # This program is free software: you can redistribute it and/or modify 
  8  # it under the terms of the GNU Affero General Public License as 
  9  # published by the Free Software Foundation, either version 3 of the 
 10  # License, or (at your option) any later version. 
 11  #  
 12  # This program is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 15  # GNU Affero General Public License for more details. 
 16  #  
 17  # You should have received a copy of the GNU Affero General Public License 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 19  #  
 20  # Author: Aleksandra Tarkowska <A(dot)Tarkowska(at)dundee(dot)ac(dot)uk>, 2008. 
 21  #  
 22  # Version: 1.0 
 23  # 
 24   
 25   
 26  import re 
 27   
 28  from django import forms 
 29  from django.forms.fields import Field, ChoiceField, EMPTY_VALUES 
 30  from django.forms.widgets import Select, SelectMultiple, MultipleHiddenInput 
 31  from django.forms import ModelChoiceField, ModelMultipleChoiceField, ValidationError 
 32  from django.utils.translation import ugettext_lazy as _ 
 33  from django.utils.encoding import smart_unicode 
 34   
 35  ################################################################## 
 36  # Fields 
 37   
38 -class OmeNameField(forms.CharField):
39 - def clean(self, value):
40 omeName = value 41 if not value: 42 raise forms.ValidationError('This field is required.') 43 if not self.is_valid_omeName(omeName): 44 raise forms.ValidationError('%s is not a valid Omename.' % omeName) 45 return omeName
46
47 - def is_valid_omeName(self, omeName):
48 omeName_pattern = re.compile(r"(?:^|\s)[a-zA-Z0-9_.]") #TODO: PATTERN !!!!!!! 49 return omeName_pattern.match(omeName) is not None
50 51 # Group queryset iterator for group form 52
53 -class ServerQuerySetIterator(object):
54 - def __init__(self, queryset, empty_label):
55 self.queryset = queryset 56 self.empty_label = empty_label
57
58 - def __iter__(self):
59 if self.empty_label is not None: 60 yield (u"", self.empty_label) 61 for obj in self.queryset: 62 if obj.server is None: 63 name = "%s:%s" % (obj.host,obj.port) 64 else: 65 name = "%s:%s" % (obj.server,obj.port) 66 yield (smart_unicode(obj.id), smart_unicode(name))
67
68 -class ServerModelChoiceField(ModelChoiceField):
69
70 - def _get_choices(self):
71 # If self._choices is set, then somebody must have manually set 72 # the property self.choices. In this case, just return self._choices. 73 if hasattr(self, '_choices'): 74 return self._choices 75 # Otherwise, execute the QuerySet in self.queryset to determine the 76 # choices dynamically. Return a fresh QuerySetIterator that has not 77 # been consumed. Note that we're instantiating a new QuerySetIterator 78 # *each* time _get_choices() is called (and, thus, each time 79 # self.choices is accessed) so that we can ensure the QuerySet has not 80 # been consumed. 81 return ServerQuerySetIterator(self.queryset, self.empty_label)
82
83 - def _set_choices(self, value):
84 # This method is copied from ChoiceField._set_choices(). It's necessary 85 # because property() doesn't allow a subclass to overwrite only 86 # _get_choices without implementing _set_choices. 87 self._choices = self.widget.choices = list(value)
88 89 choices = property(_get_choices, _set_choices) 90
91 - def clean(self, value):
92 Field.clean(self, value) 93 if value in EMPTY_VALUES: 94 return None 95 res = False 96 for q in self.queryset: 97 if long(value) == q.id: 98 res = True 99 if not res: 100 raise ValidationError(self.error_messages['invalid_choice']) 101 return value
102 103 # Group queryset iterator for group form
104 -class GroupQuerySetIterator(object):
105 - def __init__(self, queryset, empty_label):
106 self.queryset = queryset 107 self.empty_label = empty_label
108
109 - def __iter__(self):
110 if self.empty_label is not None: 111 yield (u"", self.empty_label) 112 for obj in self.queryset: 113 if hasattr(obj.name, 'val'): 114 name = obj.name.val 115 else: 116 name = obj.name 117 l = len(name) 118 if l > 35: 119 name = name[:35] + "..." 120 121 if hasattr(obj.id, 'val'): 122 oid = obj.id.val 123 else: 124 oid = obj.id 125 yield (smart_unicode(oid), smart_unicode(name))
126
127 -class GroupModelChoiceField(ModelChoiceField):
128
129 - def _get_choices(self):
130 # If self._choices is set, then somebody must have manually set 131 # the property self.choices. In this case, just return self._choices. 132 if hasattr(self, '_choices'): 133 return self._choices 134 # Otherwise, execute the QuerySet in self.queryset to determine the 135 # choices dynamically. Return a fresh QuerySetIterator that has not 136 # been consumed. Note that we're instantiating a new QuerySetIterator 137 # *each* time _get_choices() is called (and, thus, each time 138 # self.choices is accessed) so that we can ensure the QuerySet has not 139 # been consumed. 140 return GroupQuerySetIterator(self.queryset, self.empty_label)
141
142 - def _set_choices(self, value):
143 # This method is copied from ChoiceField._set_choices(). It's necessary 144 # because property() doesn't allow a subclass to overwrite only 145 # _get_choices without implementing _set_choices. 146 self._choices = self.widget.choices = list(value)
147 148 choices = property(_get_choices, _set_choices) 149
150 - def clean(self, value):
151 Field.clean(self, value) 152 if value in EMPTY_VALUES: 153 return None 154 res = False 155 for q in self.queryset: 156 if hasattr(q.id, 'val'): 157 if long(value) == q.id.val: 158 res = True 159 else: 160 if long(value) == q.id: 161 res = True 162 if not res: 163 raise ValidationError(self.error_messages['invalid_choice']) 164 return value
165
166 -class GroupModelMultipleChoiceField(GroupModelChoiceField):
167 """A MultipleChoiceField whose choices are a model QuerySet.""" 168 hidden_widget = MultipleHiddenInput 169 default_error_messages = { 170 'list': _(u'Enter a list of values.'), 171 'invalid_choice': _(u'Select a valid choice. That choice is not one of the' 172 u' available choices.'), 173 } 174
175 - def __init__(self, queryset, cache_choices=False, required=True, 176 widget=SelectMultiple, label=None, initial=None, 177 help_text=None, *args, **kwargs):
178 super(GroupModelMultipleChoiceField, self).__init__(queryset, None, 179 cache_choices, required, widget, label, initial, help_text, 180 *args, **kwargs)
181
182 - def clean(self, value):
183 if self.required and not value: 184 raise ValidationError(self.error_messages['required']) 185 elif not self.required and not value: 186 return [] 187 if not isinstance(value, (list, tuple)): 188 raise ValidationError(self.error_messages['list']) 189 final_values = [] 190 for val in value: 191 try: 192 long(val) 193 except: 194 raise ValidationError(self.error_messages['invalid_choice']) 195 else: 196 res = False 197 for q in self.queryset: 198 if hasattr(q.id, 'val'): 199 if long(val) == q.id.val: 200 res = True 201 else: 202 if long(val) == q.id: 203 res = True 204 if not res: 205 raise ValidationError(self.error_messages['invalid_choice']) 206 else: 207 final_values.append(val) 208 return final_values
209 210 # Experimenter queryset iterator for experimenter form
211 -class ExperimenterQuerySetIterator(object):
212 - def __init__(self, queryset, empty_label):
213 self.queryset = queryset 214 self.empty_label = empty_label
215
216 - def __iter__(self):
217 if self.empty_label is not None: 218 yield (u"", self.empty_label) 219 for obj in self.queryset: 220 try: 221 # lastName = obj.details.owner.lastName.val if hasattr(obj.details.owner.lastName, 'val') else "" 222 # firstName = obj.details.owner.firstName.val if hasattr(obj.details.owner.firstName, 'val') else "" 223 # middleName = obj.details.owner.middleName.val if hasattr(obj.details.owner.middleName, 'val') else "" 224 if hasattr(obj, 'getFullName'): 225 name = "%s (%s)" % (obj.getFullName(), obj.omeName) 226 else: 227 omeName = None 228 if hasattr(obj.omeName, 'val'): 229 omeName = obj.omeName.val 230 lastName = None 231 if hasattr(obj.lastName, 'val'): 232 lastName = obj.lastName.val 233 firstName = None 234 if hasattr(obj.firstName, 'val'): 235 firstName = obj.firstName.val 236 middleName = None 237 if hasattr(obj.middleName, 'val'): 238 middleName = obj.middleName.val 239 240 if middleName != '' and middleName is not None: 241 name = "%s %s. %s (%s)" % (firstName, middleName[:1], lastName, omeName) 242 else: 243 name = "%s %s (%s)" % (firstName, lastName, omeName) 244 245 246 l = len(name) 247 if l > 50: 248 name = name[:50] + "..." 249 except: 250 name = _("Unknown") 251 252 if hasattr(obj.id, 'val'): 253 oid = obj.id.val 254 else: 255 oid = obj.id 256 257 yield (smart_unicode(oid), smart_unicode(name))
258
259 -class ExperimenterModelChoiceField(ModelChoiceField):
260
261 - def _get_choices(self):
262 # If self._choices is set, then somebody must have manually set 263 # the property self.choices. In this case, just return self._choices. 264 if hasattr(self, '_choices'): 265 return self._choices 266 # Otherwise, execute the QuerySet in self.queryset to determine the 267 # choices dynamically. Return a fresh QuerySetIterator that has not 268 # been consumed. Note that we're instantiating a new QuerySetIterator 269 # *each* time _get_choices() is called (and, thus, each time 270 # self.choices is accessed) so that we can ensure the QuerySet has not 271 # been consumed. 272 return ExperimenterQuerySetIterator(self.queryset, self.empty_label)
273
274 - def _set_choices(self, value):
275 # This method is copied from ChoiceField._set_choices(). It's necessary 276 # because property() doesn't allow a subclass to overwrite only 277 # _get_choices without implementing _set_choices. 278 self._choices = self.widget.choices = list(value)
279 280 choices = property(_get_choices, _set_choices) 281
282 - def clean(self, value):
283 Field.clean(self, value) 284 if value in EMPTY_VALUES: 285 return None 286 res = False 287 for q in self.queryset: 288 if hasattr(q.id, 'val'): 289 if long(value) == q.id.val: 290 res = True 291 else: 292 if long(value) == q.id: 293 res = True 294 if not res: 295 raise ValidationError(self.error_messages['invalid_choice']) 296 return value
297
298 -class ExperimenterModelMultipleChoiceField(ExperimenterModelChoiceField):
299 """A MultipleChoiceField whose choices are a model QuerySet.""" 300 hidden_widget = MultipleHiddenInput 301 default_error_messages = { 302 'list': _(u'Enter a list of values.'), 303 'invalid_choice': _(u'Select a valid choice. That choice is not one of the' 304 u' available choices.'), 305 } 306
307 - def __init__(self, queryset, cache_choices=False, required=True, 308 widget=SelectMultiple, label=None, initial=None, 309 help_text=None, *args, **kwargs):
310 super(ExperimenterModelMultipleChoiceField, self).__init__(queryset, None, 311 cache_choices, required, widget, label, initial, help_text, 312 *args, **kwargs)
313
314 - def clean(self, value):
315 if self.required and not value: 316 raise ValidationError(self.error_messages['required']) 317 elif not self.required and not value: 318 return [] 319 if not isinstance(value, (list, tuple)): 320 raise ValidationError(self.error_messages['list']) 321 final_values = [] 322 for val in value: 323 try: 324 long(val) 325 except: 326 raise ValidationError(self.error_messages['invalid_choice']) 327 else: 328 res = False 329 for q in self.queryset: 330 if hasattr(q.id, 'val'): 331 if long(val) == q.id.val: 332 res = True 333 else: 334 if long(val) == q.id: 335 res = True 336 if not res: 337 raise ValidationError(self.error_messages['invalid_choice']) 338 else: 339 final_values.append(val) 340 return final_values
341
342 -class DefaultGroupField(ChoiceField):
343
344 - def clean(self, value):
345 """ 346 Check that the field was selected. 347 """ 348 if not value: 349 raise forms.ValidationError("Choose one of the 'Selected groups' to specify 'Default Group'.") 350 351 # Always return the cleaned data. 352 return value
353