source: sapic/users/forms.py @ 9120776

Last change on this file since 9120776 was a100574, checked in by William Páez <wpaez@…>, 6 años ago

agragadas validaciones en los campos: documento de identidad, teléfono, rif del consejo comunal y arreglado error en documento de identidad creando un vocero

  • Propiedad mode establecida a 100644
File size: 24.9 KB
Línea 
1# -*- coding: utf-8 -*-
2"""!
3Formuario para generar los formulario para los usuarios
4
5@author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
6@copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
7@date 29-05-2017
8@version 1.0.0
9"""
10from captcha.fields import CaptchaField
11from django import forms
12from django.forms import ModelForm
13from django.contrib.auth.models import User
14from django.contrib.auth.forms import (
15    UserCreationForm, PasswordResetForm,
16    SetPasswordForm, PasswordChangeForm
17    )
18from django.forms.fields import (
19    CharField, BooleanField, IntegerField
20)
21from django.forms.widgets import (
22    PasswordInput, CheckboxInput
23)
24
25from .models import UserProfile
26
27from utils.views import (
28    obtenerEstados, listMunicipios, listParroquias,
29    obtenerTipoDocumento, obtenerUnidades, obtenerTipoOrganizacion
30    )
31
32from utils.models import (
33    Estado, Municipio, Parroquia,
34    TipoDocumento, UnidadesOrganizacionSocial, TipoOrganizacion,
35    ComiteUnidadEjecutiva
36    )
37
38from organizaciones.models import (
39  OrganizacionSocial, Vocero
40  )
41
42from django.core import validators
43
44class FormularioLogin(forms.Form):
45    """!
46    Clase que permite crear el formulario de ingreso a la aplicación
47
48    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
49    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
50    @date 09-01-2017
51    @version 1.0.0
52    """
53    contrasena = CharField()
54    usuario = CharField()
55    remember_me = BooleanField()
56    captcha = CaptchaField()
57
58    class Meta:
59        fields = ('usuario', 'contrasena', 'remember_me' 'captcha')
60
61    def __init__(self, *args, **kwargs):
62        super(FormularioLogin, self).__init__(*args, **kwargs)
63        self.fields['contrasena'].widget = PasswordInput()
64        self.fields['contrasena'].widget.attrs.update({'class': 'form-control',
65        'placeholder': 'Contraseña'})
66        self.fields['usuario'].widget.attrs.update({'class': 'form-control',
67        'placeholder': 'Nombre de Usuario o Email'})
68        self.fields['remember_me'].label = "Recordar"
69        self.fields['remember_me'].widget = CheckboxInput()
70        self.fields['remember_me'].required = False
71        self.fields['captcha'].required=True
72
73
74class PasswordResetForm(PasswordResetForm):
75    """!
76    Clase que permite sobrescribir el formulario para resetear la contraseña
77
78    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
79    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
80    @date 09-01-2017
81    @version 1.0.0
82    """
83
84    def __init__(self, *args, **kwargs):
85        super(PasswordResetForm, self).__init__(*args, **kwargs)
86        self.fields['email'].widget.attrs.update({'class': 'form-control',
87                                                  'placeholder': 'Correo'})
88
89    def clean(self):
90        cleaned_data = super(PasswordResetForm, self).clean()
91        email = cleaned_data.get("email")
92
93        if email:
94            msg = "Error este email: %s, no se encuentra asociado a una cuenta\
95                  " % (email)
96            try:
97                User.objects.get(email=email)
98            except:
99                self.add_error('email', msg)
100
101
102class SetPasswordForm(SetPasswordForm):
103    """!
104    Clase que permite sobrescribir el formulario para ingresar la nueva contraseña
105
106    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
107    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
108    @date 09-01-2017
109    @version 1.0.0
110    """
111    def __init__(self, *args, **kwargs):
112        super(SetPasswordForm, self).__init__(*args, **kwargs)
113
114        self.fields['new_password1'].widget.attrs.update({'class': 'form-control',
115                                                  'placeholder': 'Ingresa la nueva contraseña'})
116
117        self.fields['new_password2'].widget.attrs.update({'class': 'form-control',
118                                                  'placeholder': 'Repite la nueva contraseña'})
119
120
121class FormularioUpdate(ModelForm):
122    """!
123    Clase que permite crear el formulario para actualizar el usuario
124
125    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
126    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
127    @date 09-01-2017
128    @version 1.0.0
129    """
130    class Meta:
131        model = User
132        fields = ['first_name', 'last_name', 'email']
133
134    def __init__(self, *args, **kwargs):
135        super(FormularioUpdate, self).__init__(*args, **kwargs)
136
137        self.fields['first_name'].widget.attrs.update({'class': 'form-control',
138        'placeholder': 'Nombres'})
139        self.fields['first_name'].required=True
140        self.fields['last_name'].widget.attrs.update({'class': 'form-control',
141        'placeholder': 'Apellidos'})
142        self.fields['last_name'].required=True
143        self.fields['email'].widget.attrs.update({'class': 'form-control',
144        'placeholder': 'Email'})
145        self.fields['email'].required=True
146
147
148class FormularioAdminUpdate(ModelForm):
149    """!
150    Clase que permite crear el formulario para actualizar el usuario por el administrador
151
152    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
153    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
154    @date 09-01-2017
155    @version 1.0.0
156    """
157
158    class Meta:
159        model = User
160        fields = ['first_name', 'last_name', 'email', 'groups',
161                  'is_staff', 'is_active']
162
163    def __init__(self, *args, **kwargs):
164         super(FormularioAdminUpdate, self).__init__(*args, **kwargs)
165
166         self.fields['first_name'].widget.attrs.update({'class': 'form-control',
167         'placeholder': 'Nombres'})
168         self.fields['first_name'].required=True
169         self.fields['last_name'].widget.attrs.update({'class': 'form-control',
170         'placeholder': 'Apellidos'})
171         self.fields['last_name'].required=True
172         self.fields['email'].widget.attrs.update({'class': 'form-control',
173         'placeholder': 'Email'})
174         self.fields['email'].required=True
175         self.fields['is_staff'].label= 'Es Administrador?'
176         self.fields['is_staff'].widget.attrs.update({'class': 'form-control','data-toggle': 'toggle','data-on': 'Si',
177                                                   'data-off': 'No'})
178         self.fields['is_active'].label= 'Estará Activo?'
179         self.fields['is_active'].widget.attrs.update({'class': 'form-control','data-toggle': 'toggle','data-on': 'Si',
180                                                   'data-off': 'No'})
181         self.fields['groups'].widget.attrs.update({'class': 'form-control'})
182
183
184class FormularioAdminRegistro(UserCreationForm):
185    """!
186    Clase que permite crear el formulario para crear usuario por el administrador
187
188    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
189    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
190    @date 09-01-2017
191    @version 1.0.0
192    """
193
194    class Meta:
195        model = User
196        fields = ['username', 'password1', 'password2',
197                  'first_name', 'last_name', 'email',
198                  'groups', 'is_staff', 'is_active']
199
200    def __init__(self, *args, **kwargs):
201        super(FormularioAdminRegistro, self).__init__(*args, **kwargs)
202
203        self.fields['first_name'].widget.attrs.update({'class': 'form-control',
204                                                       'placeholder':
205                                                       'Nombres'})
206        self.fields['first_name'].required = True
207        self.fields['last_name'].widget.attrs.update({'class': 'form-control',
208                                                      'placeholder':
209                                                      'Apellidos'})
210        self.fields['last_name'].required = True
211        self.fields['username'].widget.attrs.update({'class': 'form-control',
212                                                     'placeholder':
213                                                     'Nombre de usuario \
214                                                     (Username)'})
215        self.fields['username'].required = True
216        self.fields['password1'].widget.attrs.update({'class': 'form-control',
217                                                      'placeholder':
218                                                      'Contraseña'})
219        self.fields['password1'].required = True
220        self.fields['password2'].widget.attrs.update({'class': 'form-control',
221                                                      'placeholder':
222                                                      'Repite la Contraseña'})
223        self.fields['password2'].required = True
224        self.fields['email'].widget.attrs.update({'class': 'form-control',
225                                                  'placeholder': 'Email'})
226        self.fields['email'].required = True
227        self.fields['is_staff'].label = 'Es Administrador?'
228        self.fields['is_staff'].widget.attrs.update({'class': 'form-control','data-toggle': 'toggle','data-on': 'Si',
229                                                   'data-off': 'No'})
230        self.fields['is_active'].label = 'Estará Activo?'
231        self.fields['is_active'].widget.attrs.update({'class': 'form-control','data-toggle': 'toggle','data-on': 'Si',
232                                                   'data-off': 'No',
233                                                   'checked': 'checked'})
234        self.fields['groups'].widget.attrs.update({'class': 'form-control'})
235
236    def clean(self):
237        cleaned_data = super(FormularioAdminRegistro, self).clean()
238        email = cleaned_data.get("email")
239
240        if email:
241            msg = "Error este email: %s, ya se encuentra asociado a una cuenta\
242                  " % (email)
243            try:
244                User.objects.get(email=email)
245                self.add_error('email', msg)
246            except:
247                pass
248
249    def clean_first_name(self):
250      first_name = self.cleaned_data['first_name']
251      if not first_name.isalpha():
252          raise forms.ValidationError('El nombre no puede contener números')
253      return first_name
254
255    def clean_last_name(self):
256      last_name = self.cleaned_data['last_name']
257      if not last_name.isalpha():
258          raise forms.ValidationError('El apellido no puede contener números')
259      return last_name
260
261
262class FormularioAdminRegPerfil(ModelForm):
263    """!
264    Clase que permite crear el formulario para actualizar usuario por el administrador
265
266    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
267    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
268    @date 09-01-2017
269    @version 1.0.0
270    """
271    tipo_organizacion = forms.ModelChoiceField(queryset=TipoOrganizacion.objects.all())
272
273    organizacion = forms.ModelChoiceField(queryset=OrganizacionSocial.objects.all())
274
275    class Meta:
276        model = UserProfile
277        fields = ['fk_tipo_documento', 'id_perfil']
278
279    def __init__(self, *args, **kwargs):
280        super(FormularioAdminRegPerfil, self).__init__(*args, **kwargs)
281        self.fields['fk_tipo_documento'].empty_label = 'Seleccione el Tipo de Documento'
282        self.fields['fk_tipo_documento'].widget.attrs.update({'class': 'form-control'})
283        self.fields['fk_tipo_documento'].label= 'Tipo de Documento'
284        self.fields['fk_tipo_documento'].required=True
285        self.fields['id_perfil'].widget.attrs.update({'class': 'form-control',
286                                                      'placeholder':'00000000'})
287        self.fields['id_perfil'].label= 'Documento de Identidad'
288        self.fields['id_perfil'].required=True
289        self.fields['id_perfil'].validators=[
290            validators.RegexValidator(
291                r'^\d{8}$','Introduzca un documento de identidad válido. Se permiten 8 números.'
292            ),
293        ]
294
295        self.fields['tipo_organizacion'].widget.attrs.update({'class':'form-control'})
296        self.fields['tipo_organizacion'].empty_label = 'Seleccione Tipo Organización social'
297        self.fields['tipo_organizacion'].required = False
298
299        self.fields['organizacion'].widget.attrs.update({'class':'form-control'})
300        self.fields['organizacion'].empty_label = 'Seleccione la Organización social'
301        self.fields['organizacion'].label = 'Organizacion social'
302        self.fields['organizacion'].required = False
303
304    def clean(self):
305        cleaned_data = super(FormularioAdminRegPerfil, self).clean()
306        tipo_documento = cleaned_data.get("fk_tipo_documento")
307        documento_identidad = cleaned_data.get("id_perfil")
308        organizacion_social = cleaned_data.get("organizacion")
309
310        self.instance.id_perfil = documento_identidad
311        #self.instance.fk_org_social = organizacion_social
312        if not organizacion_social:
313          pass
314        elif documento_identidad is not None and tipo_documento is not None:
315
316            msg = "Error este Vocero %s, no se encuentra asociado a la \
317                   organizacion social: %s" % (documento_identidad,
318                                               organizacion_social)
319            try:
320                Vocero.objects.get(fk_org_social=organizacion_social,
321                                   fk_tipo_documento=tipo_documento,
322                                   documento_identidad=documento_identidad)
323            except:
324                self.add_error('id_perfil', msg)
325
326
327class PasswordChangeForm(PasswordChangeForm):
328    """!
329    Clase que sobrescribir el formulario para cambiar la contraseña
330
331    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
332    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
333    @date 09-01-2017
334    @version 1.0.0
335    """
336    def __init__(self, *args, **kwargs):
337        super(PasswordChangeForm, self).__init__(*args, **kwargs)
338
339        self.fields['old_password'].widget.attrs.update({'class': 'form-control',
340                                                  'placeholder': 'Contraseña Antigua'})
341        self.fields['new_password1'].widget.attrs.update({'class': 'form-control',
342                                                  'placeholder': 'Ingresa la nueva contraseña'})
343
344        self.fields['new_password2'].widget.attrs.update({'class': 'form-control',
345                                                  'placeholder': 'Repite la nueva contraseña'})
346
347
348
349class FormularioAdminRegVoceros(UserCreationForm):
350    """!
351     Clase que permite crear el formulario para crear usuarios voceros por el administrador
352
353    @author Ing. Leonel P. Hernandez M. (lhernandez at cenditel.gob.ve)
354    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
355    @date 04-08-2017
356    @version 1.0.0
357    """
358
359    class Meta:
360        model = User
361        fields = ['username', 'password1', 'password2',
362                  'first_name', 'last_name', 'email',
363                  'is_active']
364
365
366    def __init__(self, *args, **kwargs):
367        super(FormularioAdminRegVoceros, self).__init__(*args, **kwargs)
368
369        self.fields['first_name'].widget.attrs.update({'class': 'form-control',
370                                                       'placeholder':
371                                                       'Nombres'})
372        self.fields['first_name'].required = True
373        self.fields['last_name'].widget.attrs.update({'class': 'form-control',
374                                                      'placeholder':
375                                                      'Apellidos'})
376        self.fields['last_name'].required = True
377        self.fields['username'].widget.attrs.update({'class': 'form-control',
378                                                     'placeholder':
379                                                     'Nombre de usuario \
380                                                     (Username)'})
381        self.fields['username'].required = True
382        self.fields['password1'].widget.attrs.update({'class': 'form-control',
383                                                      'placeholder':
384                                                      'Contraseña'})
385        self.fields['password1'].required = True
386        self.fields['password2'].widget.attrs.update({'class': 'form-control',
387                                                      'placeholder':
388                                                      'Repite la Contraseña'})
389        self.fields['password2'].required = True
390        self.fields['email'].widget.attrs.update({'class': 'form-control',
391                                                  'placeholder': 'Email'})
392
393        self.fields['is_active'].label = 'Estará Activo?'
394        self.fields['is_active'].widget.attrs.update({'class': 'form-control','data-toggle': 'toggle','data-on': 'Si',
395                                                   'data-off': 'No',
396                                                   'checked': 'checked'})
397
398    def clean(self):
399        cleaned_data = super(FormularioAdminRegVoceros, self).clean()
400        email = cleaned_data.get("email")
401
402        if email:
403            msg = "Error este email: %s, ya se encuentra asociado a otra cuenta\
404                  " % (email)
405            try:
406                User.objects.get(email=email)
407                self.add_error('email', msg)
408            except:
409                pass
410
411    def clean_first_name(self):
412      first_name = self.cleaned_data['first_name']
413      if not first_name.isalpha():
414          raise forms.ValidationError('El nombre no puede contener números')
415      return first_name
416
417    def clean_last_name(self):
418      last_name = self.cleaned_data['last_name']
419      if not last_name.isalpha():
420          raise forms.ValidationError('El apellido no puede contener números')
421      return last_name
422
423
424class FormularioRegVoceros(ModelForm):
425
426    tipo_organizacion = forms.ModelChoiceField(queryset=TipoOrganizacion.objects.all())
427
428    comite_unidad_ejecutiva = forms.ModelChoiceField(queryset=ComiteUnidadEjecutiva.objects.all())
429
430    estado = forms.ModelChoiceField(queryset=Estado.objects.all())
431
432    municipio = forms.ModelChoiceField(queryset=Municipio.objects.all())
433
434    documento = forms.IntegerField()
435
436    organizacion = forms.ModelChoiceField(queryset=OrganizacionSocial.objects.all())
437
438    class Meta:
439        model = Vocero
440        fields = ['organizacion', 'fk_tipo_documento', 'documento',
441                  'tipo_organizacion', 'fk_rol_unidad', 'sector',
442                  'casa_edificio_calle', 'comite_unidad_ejecutiva', 'localidad',
443                  'telefono', 'estado', 'municipio']
444
445    def __init__(self, *args, **kwargs):
446        super(FormularioRegVoceros, self).__init__(*args, **kwargs)
447
448        self.fields['fk_tipo_documento'].widget.attrs.update({'class':'form-control'})
449        self.fields['fk_tipo_documento'].empty_label = 'Seleccione El tipo de Documento'
450        self.fields['fk_tipo_documento'].label = 'Tipo de Documento'
451        self.fields['fk_tipo_documento'].required = True
452
453        self.fields['documento'].widget.attrs.update({'class':'form-control', 'placeholder':'00000000'})
454        self.fields['documento'].label = 'Documento de Identidad'
455        self.fields['documento'].required=True
456        self.fields['documento'].validators=[
457            validators.RegexValidator(
458                r'^\d{8}$','Introduzca un documento de identidad válido. Se permiten 8 números.'
459            ),
460        ]
461
462        self.fields['tipo_organizacion'].widget.attrs.update({'class':'form-control'})
463        self.fields['tipo_organizacion'].empty_label = 'Seleccione Tipo Organización social'
464        self.fields['tipo_organizacion'].required = True
465
466        self.fields['organizacion'].widget.attrs.update({'class':'form-control'})
467        self.fields['organizacion'].empty_label = 'Seleccione la Organización social'
468        self.fields['organizacion'].label = 'Organizacion social'
469        self.fields['organizacion'].required = True
470
471        self.fields['fk_rol_unidad'].widget.attrs.update({'class':'form-control'})
472        self.fields['fk_rol_unidad'].empty_label = 'Seleccione el Rol'
473        self.fields['fk_rol_unidad'].label = 'Rol del Vocero'
474        self.fields['fk_rol_unidad'].required = True
475
476        self.fields['comite_unidad_ejecutiva'].widget.attrs.update({'class':'form-control'})
477        self.fields['comite_unidad_ejecutiva'].empty_label = 'Seleccione el Comite'
478        self.fields['comite_unidad_ejecutiva'].required = False
479
480        self.fields['estado'].widget.attrs.update({'class':'form-control'})
481        self.fields['estado'].empty_label = 'Seleccione Estado'
482        self.fields['estado'].required = True
483
484        self.fields['municipio'].widget.attrs.update({'class':'form-control'})
485        self.fields['municipio'].empty_label = 'Seleccione Municipio'
486        self.fields['municipio'].required = True
487
488        self.fields['localidad'].widget.attrs.update({'class':'form-control'})
489        self.fields['localidad'].empty_label = 'Seleccione Parroquia'
490        self.fields['localidad'].required = True
491
492        self.fields['sector'].widget = forms.Textarea()
493        self.fields['sector'].widget.attrs.update(
494                                        {'class': 'form-control',
495                                         'placeholder':
496                                         'Sector del vocero'})
497        self.fields['sector'].required = False
498
499        self.fields['casa_edificio_calle'].widget = forms.Textarea()
500        self.fields['casa_edificio_calle'].widget.attrs.update(
501                                        {'class': 'form-control',
502                                         'placeholder':
503                                         'Casa/Edificio/Calle del vocero'})
504        self.fields['casa_edificio_calle'].required = False
505
506        self.fields['telefono'].widget.attrs.update({'class': 'form-control',
507                                                 'placeholder': '+58-000-0000000'})
508        self.fields['telefono'].required = False
509        self.fields['telefono'].validators=[
510            validators.RegexValidator(
511                r'^\+\d{2}-\d{3}-\d{7}$','Introduzca un número de teléfono válido. El formato debe ser +58-000-0000000.'
512            ),
513        ]
514
515    def clean(self):
516        cleaned_data = super(FormularioRegVoceros, self).clean()
517        tipo_documento = cleaned_data.get("fk_tipo_documento")
518        documento_identidad = cleaned_data.get("documento")
519        organizacion_social = cleaned_data.get("organizacion")
520
521        self.instance.documento_identidad = documento_identidad
522        self.instance.fk_org_social = organizacion_social
523
524        if documento_identidad is not None and tipo_documento is not None:
525
526            msg = "Error este Vocero %s, no se encuentra asociado a la \
527                   organizacion social: %s" % (documento_identidad,
528                                               organizacion_social)
529            try:
530                Vocero.objects.get(fk_org_social=organizacion_social,
531                                   fk_tipo_documento=tipo_documento,
532                                   documento_identidad=documento_identidad)
533            except:
534                self.add_error('documento', msg)
535
536class FormupdatePerfilVoceros(ModelForm):
537
538    tipo_organizacion = forms.ModelChoiceField(queryset=TipoOrganizacion.objects.all())
539
540    class Meta:
541        model = Vocero
542        fields = ['fk_org_social', 'fk_tipo_documento', 'documento_identidad',
543                  'tipo_organizacion', 'fk_rol_unidad', 'tipo_organizacion']
544
545    def __init__(self, *args, **kwargs):
546        super(FormupdatePerfilVoceros, self).__init__(*args, **kwargs)
547        self.fields['fk_tipo_documento'].widget.attrs.update({'class':'form-control',
548                                                              'readonly':'readonly'})
549        self.fields['fk_tipo_documento'].empty_label = 'Seleccione El tipo de Documento'
550        self.fields['fk_tipo_documento'].label = 'Tipo de Documento'
551        self.fields['fk_tipo_documento'].required = True
552
553        self.fields['documento_identidad'].widget.attrs.update({'class':'form-control',
554                                                      'readonly':'readonly'})
555        self.fields['documento_identidad'].label = 'Documento de Identidad'
556        self.fields['documento_identidad'].required=True
557
558        self.fields['tipo_organizacion'].widget.attrs.update({'class':'form-control'})
559        self.fields['tipo_organizacion'].empty_label = 'Seleccione Tipo Organización social'
560        self.fields['tipo_organizacion'].required = True
561
562        self.fields['fk_org_social'].widget.attrs.update({'class':'form-control'})
563        self.fields['fk_org_social'].empty_label = 'Seleccione la Organización social'
564        self.fields['fk_org_social'].label = 'Organizacion social'
565        self.fields['fk_org_social'].required = True
566
567        self.fields['fk_rol_unidad'].widget.attrs.update({'class':'form-control'})
568        self.fields['fk_rol_unidad'].empty_label = 'Seleccione el Rol'
569        self.fields['fk_rol_unidad'].label = 'Rol del Vocero'
570        self.fields['fk_rol_unidad'].required = True
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.