Example #1
0
class RegistrarEditForm(EditForm):
    def __init__(self, *args, **kwargs):
        super(RegistrarEditForm, self).__init__(
            layout_class=RegistrarEditFormLayout,
            enctype="multipart/form-data", *args, **kwargs)

    id = HiddenDecimalField()
    handle = CharField(label=_('Handle')) # registrar identification
    name = CharField(label=_('Name'), required=False) # registrar name
    organization = CharField(label=_('Organization'), required=False) # organization name

    street1 = CharField(label=_('Street1'), required=False) # address part 1
    street2 = CharField(label=_('Street2'), required=False) # address part 2
    street3 = CharField(label=_('Street3'), required=False) # address part 3
    city = CharField(label=_('City'), required=False) # city of registrar headquaters
    stateorprovince = CharField(label=_('State'), required=False) # address part
    postalcode = CharField(label=_('ZIP'), required=False, max_length=32) # address part
    country = ChoiceField(
        label=_('Country'), 
        choices=CorbaLazyRequestIterStruct(
            'Admin', None, 'getCountryDescList', ['cc', 'name'], None), 
        initial=CorbaLazyRequest('Admin', None, 'getDefaultCountry', None), 
        required=False) # country code
    
    ico = CharField(label=_('ICO'), required=False, max_length=50)
    dic = CharField(label=_('DIC'), required=False, max_length=50)
    varSymb = CharField(label=_('Var. Symbol'), required=False, max_length=10)
    vat = BooleanField(label=_('DPH'), required=False)

    telephone = CharField(label=_('Telephone'), required=False, max_length=32) # phne number
    fax = CharField(label=_('Fax'), required=False, max_length=32) # fax number
    email = CharField(label=_('Email'), required=False) # contact email
    url = CharField(label=_('URL'), required=False) # URL
    hidden = BooleanField(label=_('System registrar'), required=False) # System registrar

    visible_fieldsets_ids = HiddenField(
        required=False, id="visible_fieldsets_ids_field_id")
    
    access = FormSetField(
        label=_('Authentication'), form_class=AccessEditForm, can_delete=True,
        formset_layout=DivFormSetLayout)
    zones = FormSetField(
        label=_('Zones'), form_class=ZoneEditForm, 
        can_delete=False, formset_layout=DivFormSetLayout)
    groups = FormSetField(
        label=_('Groups'), form_class=SingleGroupEditForm, can_delete=True)
    certifications = FormSetField(
        label=_('Certifications'), form_class=CertificationEditForm, 
        can_delete=False)

    sections = (
        (_("Registrar data"), ("registrar_data_id"), (
            "handle", "name", "organization", 'street1', 'street2', 
            'street3', 'city', 'postalcode', 'stateorprovince', 'country',
            "postalCode", "ico", "dic", "varSymb", "vat", "telephone", "fax",
            "email", "url", "hidden", "id", "visible_fieldsets_ids"),
            HideableSimpleFieldsetFormSectionLayout),
        (_("Authentication"), ("authentications_id"), ("access"), 
            HideableNestedFieldsetFormSectionLayout),
        (_("Zones"), ("zones_id"), ("zones"), 
            HideableNestedFieldsetFormSectionLayout),
        (_("Groups"), ("groups_id"), ("groups"), 
            HideableNestedFieldsetFormSectionLayout),
        (_("Certifications"), ("certifications_id"), ("certifications"), 
            HideableNestedFieldsetFormSectionLayout))
    
    def filter_base_fields(self):
        """ Filters base fields against user negative permissions, so if 
            the user has nperm on the field we delete it from base_fields.
        """
        if self.nperm_names:
            user = cherrypy.session.get('user', None)
            if user is None:
                self.base_fields = SortedDict({})
            else:
                object_name = self.get_object_name()
                formset_fields = [
                    self.base_fields['access'],
                    self.base_fields['zones'],
                    self.base_fields['groups'],
                    self.base_fields['certifications']]
                for field in formset_fields:
                    if not user.check_nperms(['%s.%s.%s' % (
                            nperm_name, object_name, field.get_nperm()) for 
                            nperm_name in self.nperm_names], 'one'):
                        field.permitted = True
                    else:
                        field.permitted = False
                filtered_base_fields = SortedDict(
                    [(name, field) for name, field in self.base_fields.items()]
                )
                self.base_fields = filtered_base_fields

    def fire_actions(self, *args, **kwargs):
        try:
            reg = kwargs["updated_registrar"]
        except KeyError:
            raise RuntimeError(
                "RegistrarDataEditForm: Failed to fetch "
                "updated registrar from kwargs.")
        session = utils.get_corba_session()
        try:
            reg_id = session.updateRegistrar(reg)
        except ccReg.Admin.UpdateFailed, e:
            raise UpdateFailedError(
                "Updating registrar failed. Perhaps you tried to "
                "create a registrar with an already used handle?")
        # Set created/updated registrar id to result (it is used in ADIF
        # registrar page and other fire_action methods).
        kwargs["result"]['reg_id'] = reg_id
        # Fire actions for groups.
        self.fields["groups"].fire_actions(reg_id=reg_id, *args, **kwargs)
        self.fields["certifications"].fire_actions(
            reg_id=reg_id, *args, **kwargs)
Example #2
0
class BaseDetail(div):
    editable = False
    nperm_names = ['read']

    def __init__(self,
                 data,
                 history,
                 label_suffix=':',
                 display_only=None,
                 sections=None,
                 layout_class=SectionDetailLayout,
                 is_nested=False,
                 all_no_access=False,
                 *content,
                 **kwd):
        super(BaseDetail, self).__init__(*content, **kwd)
        self.tag = u''
        self.media_files.append('/css/details.css')

        self.history = history
        self.data = data or {}
        if data is not None:
            if not isinstance(data,
                              types.DictType):  # data is some corba object
                self.data = data.__dict__
            else:  # data is dict
                self.data = data

        self.label_suffix = label_suffix
        self.layout_class = layout_class
        self.is_nested = is_nested
        self.all_no_access = all_no_access

        # check if display_only contains correct field names
        if display_only:
            for field_name in display_only:
                if self.base_fields.get(field_name) is None:
                    raise RuntimeError(
                        _('Incorrect field name "%s" specified in %s. display_only list!'
                          ) % (field_name, repr(self)))

        self.display_only = display_only

        # Sections can be defined as class attribute of detail, so take care
        # to create attribute but not override it, if it already exists.
        if getattr(self, 'sections', None) is None:
            self.sections = None
        if sections is not None:
            self.sections = sections

        self.fields = None
        self.filter_base_fields()
        self.build_fields()
        self.set_fields_values()

        # if self.section is None, create one default section with all fields:
        if self.sections is None or sections == 'all_in_one':
            self.sections = [[None, self.fields.keys()]]

    def filter_base_fields(self):
        """ Filters base fields against user negative permissions,
            so if user has nperm on field we delete it from base_fields.
        """
        user = cherrypy.session.get('user', None)
        if user is None:
            self.base_fields = SortedDict({})
        else:
            self.base_fields = SortedDict([
                (name, field) for name, field in self.base_fields.items()
                if not self.display_only or field.name in self.display_only
            ])

    def build_fields(self):
        user = cherrypy.session.get('user', None)
        if user is None:
            self.fields = SortedDict({})
        else:
            self.fields = self.base_fields.deepcopy()
            object_name = self.get_object_name()
            for field in self.fields.values():
                field_nperm = field.get_nperm()
                if self.all_no_access or user.check_nperms(
                    ['%s.%s.%s' % (nperm_name, object_name, field_nperm) for \
                        nperm_name in self.nperm_names], 'one'):
                    field.access = False
                field.owner_detail = self

    def set_fields_values(self):
        for field in self.fields.values():
            field.value = field.value_from_data(self.data)

    @classmethod
    def get_object_name(cls):
        return cls.__name__[:-len('Detail')].lower()

    def add_to_bottom(self):
        ''' Usualy used for filterpanel and/or edit link. '''
        if self.editable:
            self.add(
                p(
                    a(
                        attr(href=u'../edit/?id=' +
                             unicode(self.data.get('id'))), _('Edit'))))

    def render(self, indent_level=0):
        self.content = [
        ]  # empty previous content (if render would be called moretimes, there would be multiple forms instead one )
        self.add(self.layout_class(self))
        if self.check_nperms():
            # TODO: render error!
            return div("ERROR NO PERMS").render()
            pass
        if not self.is_nested:
            self.add_to_bottom()
        return super(BaseDetail, self).render(indent_level)

    def check_nperms(self):
        return False

    @classmethod
    def get_nperms(cls):
        nperms = []
        for field in cls.base_fields.values():
            field_nperm = field.get_nperm()
            field_nperms = [
                '%s.%s.%s' % (nperm_name, cls.get_object_name(), field_nperm)
                for nperm_name in cls.nperm_names
            ]
            nperms.extend(field_nperms)
        return nperms
Example #3
0
class RegistrarEditForm(EditForm):
    def __init__(self, *args, **kwargs):
        super(RegistrarEditForm,
              self).__init__(layout_class=RegistrarEditFormLayout,
                             enctype="multipart/form-data",
                             *args,
                             **kwargs)

    handle = CharField(label=_('Handle'))  # registrar identification
    name = CharField(label=_('Name'), required=False)  # registrar name
    organization = CharField(label=_('Organization'),
                             required=False)  # organization name

    street1 = CharField(label=_('Street1'), required=False)  # address part 1
    street2 = CharField(label=_('Street2'), required=False)  # address part 2
    street3 = CharField(label=_('Street3'), required=False)  # address part 3
    city = CharField(label=_('City'),
                     required=False)  # city of registrar headquaters
    stateorprovince = CharField(label=_('State'),
                                required=False)  # address part
    postalcode = CharField(label=_('ZIP'), required=False,
                           max_length=32)  # address part
    country = ChoiceField(label=_('Country'),
                          choices=CorbaLazyRequestIterStruct(
                              'Admin', None, 'getCountryDescList',
                              ['cc', 'name'], None),
                          initial=CorbaLazyRequest('Admin', None,
                                                   'getDefaultCountry', None),
                          required=False)  # country code

    ico = CharField(label=_('ICO'), required=False, max_length=50)
    dic = CharField(label=_('DIC'), required=False, max_length=50)
    varSymb = CharField(label=_('Var. Symbol'), required=False, max_length=10)
    vat = BooleanField(label=_('DPH'), required=False)

    telephone = CharField(label=_('Telephone'), required=False,
                          max_length=32)  # phne number
    fax = CharField(label=_('Fax'), required=False,
                    max_length=32)  # fax number
    email = CharField(label=_('Email'), required=False)  # contact email
    url = CharField(label=_('URL'), required=False)  # URL
    hidden = BooleanField(label=_('System registrar'),
                          required=False)  # System registrar

    visible_fieldsets_ids = HiddenField(required=False,
                                        id="visible_fieldsets_ids_field_id")

    access = FormSetField(label=_('Authentication'),
                          form_class=AccessEditForm,
                          can_delete=True,
                          formset_layout=DivFormSetLayout)
    zones = FormSetField(label=_('Zones'),
                         form_class=ZoneEditForm,
                         can_delete=False,
                         formset_layout=DivFormSetLayout)
    groups = FormSetField(label=_('Groups'),
                          form_class=SingleGroupEditForm,
                          can_delete=True)
    certifications = FormSetField(label=_('Certifications'),
                                  form_class=CertificationEditForm,
                                  can_delete=False)

    sections = ((_("Registrar data"), ("registrar_data_id"),
                 ("handle", "name", "organization", 'street1', 'street2',
                  'street3', 'city', 'postalcode', 'stateorprovince',
                  'country', "postalCode", "ico", "dic", "varSymb", "vat",
                  "telephone", "fax", "email", "url", "hidden", "id",
                  "visible_fieldsets_ids"),
                 HideableSimpleFieldsetFormSectionLayout),
                (_("Authentication"), ("authentications_id"), ("access"),
                 HideableNestedFieldsetFormSectionLayout),
                (_("Zones"), ("zones_id"), ("zones"),
                 HideableNestedFieldsetFormSectionLayout),
                (_("Groups"), ("groups_id"), ("groups"),
                 HideableNestedFieldsetFormSectionLayout),
                (_("Certifications"), ("certifications_id"),
                 ("certifications"), HideableNestedFieldsetFormSectionLayout))

    def filter_base_fields(self):
        """ Filters base fields against user negative permissions, so if
            the user has nperm on the field we delete it from base_fields.
        """
        if self.nperm_names:
            user = cherrypy.session.get('user', None)
            if user is None:
                self.base_fields = SortedDict({})
            else:
                object_name = self.get_object_name()
                formset_fields = [
                    self.base_fields['access'], self.base_fields['zones'],
                    self.base_fields['groups'],
                    self.base_fields['certifications']
                ]
                for field in formset_fields:
                    if not user.check_nperms([
                            '%s.%s.%s' %
                        (nperm_name, object_name, field.get_nperm())
                            for nperm_name in self.nperm_names
                    ], 'one'):
                        field.permitted = True
                    else:
                        field.permitted = False
                filtered_base_fields = SortedDict([
                    (name, field) for name, field in self.base_fields.items()
                ])
                self.base_fields = filtered_base_fields

    def fire_actions(self, *args, **kwargs):
        try:
            reg = kwargs["updated_registrar"]
        except KeyError:
            raise RuntimeError("RegistrarDataEditForm: Failed to fetch "
                               "updated registrar from kwargs.")
        session = utils.get_corba_session()
        try:
            reg_id = session.updateRegistrar(reg)
        except ccReg.Admin.UpdateFailed:
            raise UpdateFailedError(
                "Updating registrar failed. Perhaps you tried to "
                "create a registrar with an already used handle or variable symbol?"
            )
        # Set created/updated registrar id to result (it is used in ADIF
        # registrar page and other fire_action methods).
        kwargs["result"]['reg_id'] = reg_id
        # Fire actions for groups.
        self.fields["groups"].fire_actions(reg_id=reg_id, *args, **kwargs)
        self.fields["certifications"].fire_actions(reg_id=reg_id,
                                                   *args,
                                                   **kwargs)
Example #4
0
class BaseDetail(div):
    editable = False
    nperm_names = ['read']
    
    def __init__(self, data, history, label_suffix=':', display_only = None, 
                 sections = None, layout_class=SectionDetailLayout,
                 is_nested = False, all_no_access=False, *content, **kwd):
        super(BaseDetail, self).__init__(*content, **kwd)
        self.tag = u''
        self.media_files.append('/css/details.css')

        self.history = history
        self.data = data or {}
        if data is not None:
            if not isinstance(data, types.DictType): # data is some corba object
                self.data = data.__dict__
            else: # data is dict
                self.data = data
            
        self.label_suffix = label_suffix
        self.layout_class = layout_class
        self.is_nested = is_nested
        self.all_no_access = all_no_access
        
        # check if display_only contains correct field names
        if display_only:
            for field_name in display_only:
                if self.base_fields.get(field_name) is None:
                    raise RuntimeError(_('Incorrect field name "%s" specified in %s. display_only list!') % (field_name, repr(self)))
             
        self.display_only = display_only
        
        # Sections can be defined as class attribute of detail, so take care
        # to create attribute but not override it, if it already exists.
        if getattr(self, 'sections', None) is None: 
            self.sections = None
        if sections is not None:
            self.sections = sections

        self.fields = None
        self.filter_base_fields()
        self.build_fields()
        self.set_fields_values()

        # if self.section is None, create one default section with all fields:
        if self.sections is None or sections == 'all_in_one':
            self.sections = [[None, self.fields.keys()]]

    def filter_base_fields(self):
        """ Filters base fields against user negative permissions, 
            so if user has nperm on field we delete it from base_fields.
        """
        user = cherrypy.session.get('user', None)
        if user is None:
            self.base_fields = SortedDict({})
        else:
            self.base_fields = SortedDict(
                [(name, field) for name, field in self.base_fields.items() 
                    if not self.display_only or field.name in self.display_only])
    
    def build_fields(self):
        user = cherrypy.session.get('user', None)
        if user is None:
            self.fields = SortedDict({})
        else:
            self.fields = self.base_fields.deepcopy()
            object_name = self.get_object_name()
            for field in self.fields.values():
                field_nperm = field.get_nperm()
                if self.all_no_access or user.check_nperms(
                    ['%s.%s.%s' % (nperm_name, object_name, field_nperm) for \
                        nperm_name in self.nperm_names], 'one'):
                            field.access = False
                field.owner_detail = self
        
    def set_fields_values(self):
        for field in self.fields.values():
            if field.access:
                field.value = field.value_from_data(self.data)
            else:
                field.value = field.value_from_data({}) # emtpy dict as there are no data
                field.make_content_no_access()
    
    @classmethod
    def get_object_name(cls):
        return cls.__name__[:-len('Detail')].lower()
    
    def add_to_bottom(self):
        ''' Usualy used for filterpanel and/or edit link. '''
        if self.editable:
            self.add(p(a(attr(href=u'../edit/?id=' + unicode(self.data.get('id'))), _('Edit'))))
    
    def render(self, indent_level=0):
        self.content = [] # empty previous content (if render would be called moretimes, there would be multiple forms instead one )
        self.add(self.layout_class(self))
        if self.check_nperms():
            # TODO: render error!
            return div("ERROR NO PERMS").render()
            pass
        if not self.is_nested:
            self.add_to_bottom()
        return super(BaseDetail, self).render(indent_level)        

    def check_nperms(self):
        return False
    
    @classmethod
    def get_nperms(cls):
        nperms = []
        for field in cls.base_fields.values():
            field_nperm = field.get_nperm()
            field_nperms = ['%s.%s.%s' % (nperm_name, cls.get_object_name(), field_nperm) for nperm_name in cls.nperm_names]
            nperms.extend(field_nperms)
        return nperms
Example #5
0
class BaseForm(form):
    # This is the main implementation of all the Form logic. Note that this
    # class is different than Form. See the comments by the Form class for more
    # information. Any improvements to the form API should be made to *this*
    # class, not to the Form class
    nperm_names = []
    name_postfix = ''
    _submit_button_text = 'OK'

    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=':', layout_class=TableFormLayout,
                 submit_button_text=None, is_nested=False, empty_permitted=False, *content, **kwd):
        super(BaseForm, self).__init__(*content, **kwd)

        if not is_nested:
            self.tag = u'form'
        else:
            self.tag = u''
        self.is_bound = data is not None or files is not None
        self.data = data or {}
        self.files = files or {}
        self.auto_id = auto_id
        self.prefix = prefix
        self.initial = initial or {}
        self.error_class = error_class
        self.label_suffix = label_suffix
        self._errors = None  # Stores the errors after clean() has been called.
        self.layout_class = layout_class
        self.is_nested = is_nested
        if submit_button_text is not None:
            self._submit_button_text = submit_button_text
        self.empty_permitted = empty_permitted
        self._changed_data = None
        # The base_fields class attribute is the *class-wide* definition of
        # fields. Because a particular *instance* of the class might want to
        # alter self.fields, we create self.fields here by copying base_fields.
        # Instances should always modify self.fields; they should not modify
        # self.base_fields.
        self.fields = None
        self.filter_base_fields()
        self.build_fields()
        self.set_fields_values()

    def filter_base_fields(self):
        """ Filters base fields against user negative permissions, so if
            the user has nperm on the field we delete it from base_fields.
        """
        if self.nperm_names:
            user = cherrypy.session.get('user', None)
            if user is None:
                self.base_fields = SortedDict({})
            else:
                object_name = self.get_object_name()
                filtered_base_fields = SortedDict(
                    [(name, field) for name, field in self.base_fields.items()
                     if not user.check_nperms(['%s.%s.%s' % (nperm_name, object_name, field.get_nperm()) for nperm_name in self.nperm_names], 'one')
                    ]
                )
                self.base_fields = filtered_base_fields

    @classmethod
    def get_object_name(cls):
        return cls.__name__[:-len(cls.name_postfix)].lower()

    def build_fields(self):
        self.fields = self.base_fields.deepcopy()
        for field in self.fields.values():
            field.owner_form = self
            field.name = self.add_prefix(field.name_orig)

    def set_fields_values(self):
        # setting initials is independent on whether form is bound or not:
        for field in self.fields.values():
            data = self.initial.get(field.name_orig, field.initial)
            if callable(data):
                data = data()
            if data is not None:
                field.initial = data

        if not self.is_bound:
            if self.initial:
                for field in self.fields.values():
                    if field.initial is not None:
                        field.value_is_from_initial = True
                        field.value = field.initial
        else:
            for field in self.fields.values():
                field.value = field.value_from_datadict(self.data)

    def __iter__(self):
        for field in self.fields.values():
            yield field

    def __getitem__(self, name):
        "Returns a field with the given name."
        try:
            field = self.fields[name]
        except KeyError:
            raise KeyError('Key %r not found in Form' % name)
        return field

    def _get_errors(self):
        "Returns an ErrorDict for the data provided for the form"
        try:
            if self._errors is None:
                self.full_clean()
            return self._errors
        except AttributeError:
            raise RuntimeError('Camouflaged AttributeError from _get_errors, original error: \n %s' % unicode(traceback.format_exc()))

    errors = property(_get_errors)

    def is_valid(self):
        """
        Returns True if the form has no errors. Otherwise, False. If errors are
        being ignored, returns False.
        """
        return self.is_bound and not bool(self.errors)

    def add_prefix(self, field_name):
        """
        Returns the field name with a prefix appended, if this Form has a
        prefix set.

        Subclasses may wish to override.
        """
        return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name

    def render(self, indent_level=0):
        self.content = []  # empty previous content (if render would be called more times, there would be multiple forms instead one )
        self.add(self.layout_class(self))
        return super(BaseForm, self).render(indent_level)

    def non_field_errors(self):
        """
        Returns an ErrorList of errors that aren't associated with a particular
        field - -i.e., from Form.clean(). Returns an empty ErrorList if there
        are none.
        """
        result = self.errors.get(NON_FIELD_ERRORS, None)
        if not result:
            result = self.errors[NON_FIELD_ERRORS] = self.error_class()
        return result

    def is_empty(self, exceptions=None):
        """
        Returns True if this form has been bound and all fields that aren't
        listed in exceptions are empty.
        """
        # TODO: This could probably use some optimization
        exceptions = exceptions or []
        for name, field in self.fields.items():
            if name in exceptions:
                continue
            # value_from_datadict() gets the data from the dictionary.
            # Each widget type knows how to retrieve its own data, because some
            # widgets split data over several HTML fields.
            # HACK: ['', ''] and [None, None] deal with SplitDateTimeWidget. This should be more robust.
            if field.value not in (None, '', ['', ''], [None, None]):
                return False
        return True

    def full_clean(self):
        """
        Cleans all of self.data and populates self._errors and
        self.cleaned_data.
        """
        self._errors = ErrorDict()
        if not self.is_bound:  # Stop further processing.
            return
        self.cleaned_data = {}
        if self.empty_permitted and not self.has_changed():
            self.cleaned_data = None
            return
        for name, field in self.fields.items():
            self.clean_field(name, field)
        try:
            self.cleaned_data = self.clean()
        except ValidationError, e:
            self._errors[NON_FIELD_ERRORS] = e.messages
        if self._errors:
            delattr(self, 'cleaned_data')
Example #6
0
class BaseForm(form):
    # This is the main implementation of all the Form logic. Note that this
    # class is different than Form. See the comments by the Form class for more
    # information. Any improvements to the form API should be made to *this*
    # class, not to the Form class
    nperm_names = []
    name_postfix = ''
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=':', layout_class=TableFormLayout, 
                 is_nested = False, empty_permitted=False, *content, **kwd):
        super(BaseForm, self).__init__(*content, **kwd)
        
        if not is_nested:
            self.tag = u'form'
        else:
            self.tag = u''
        self.is_bound = data is not None or files is not None
        self.data = data or {}
        self.files = files or {}
        self.auto_id = auto_id
        self.prefix = prefix
        self.initial = initial or {}
        self.error_class = error_class
        self.label_suffix = label_suffix
        self._errors = None # Stores the errors after clean() has been called.
        self.layout_class = layout_class
        self.is_nested = is_nested
        self.empty_permitted = empty_permitted
        self._changed_data = None
        # The base_fields class attribute is the *class-wide* definition of
        # fields. Because a particular *instance* of the class might want to
        # alter self.fields, we create self.fields here by copying base_fields.
        # Instances should always modify self.fields; they should not modify
        # self.base_fields.
        self.fields = None
        self.filter_base_fields()
        self.build_fields()
        self.set_fields_values()
    
    def filter_base_fields(self):
        """ Filters base fields against user negative permissions, so if 
            the user has nperm on the field we delete it from base_fields.
        """
        if self.nperm_names:
            user = cherrypy.session.get('user', None)
            if user is None:
                self.base_fields = SortedDict({})
            else:
                object_name = self.get_object_name()
                filtered_base_fields = SortedDict(
                    [(name, field) for name, field in self.base_fields.items()
                     if not user.check_nperms(['%s.%s.%s' % (nperm_name, object_name, field.get_nperm()) for nperm_name in self.nperm_names], 'one')
                    ]
                )
                self.base_fields = filtered_base_fields
    
    @classmethod
    def get_object_name(cls):
        return cls.__name__[:-len(cls.name_postfix)].lower()
    
    def build_fields(self):
        self.fields = self.base_fields.deepcopy()
        for field in self.fields.values():
            field.owner_form = self
            field.name = self.add_prefix(field.name_orig)
        
    def set_fields_values(self):
        # setting initials is independent on whether form is bound or not:
        for field in self.fields.values():
            data = self.initial.get(field.name_orig, field.initial)
            if callable(data):
                data = data()
            if data is not None:
                field.initial = data

        if not self.is_bound:
            if self.initial:
                for field in self.fields.values():
                    if field.initial is not None:
                        field.value_is_from_initial = True
                        field.value = field.initial
        else:
            for field in self.fields.values():
                field.value = field.value_from_datadict(self.data)
        
    def __iter__(self):
        for field in self.fields.values():
            yield field

    def __getitem__(self, name):
        "Returns a field with the given name."
        try:
            field = self.fields[name]
        except KeyError:
            raise KeyError('Key %r not found in Form' % name)
        return field

    def _get_errors(self):
        "Returns an ErrorDict for the data provided for the form"
        try:
            if self._errors is None:
                self.full_clean()
            return self._errors
        except AttributeError:
            raise RuntimeError('Camouflaged AttributeError from _get_errors, original error: \n %s' % unicode(traceback.format_exc()))
            
    errors = property(_get_errors)

    def is_valid(self):
        """
        Returns True if the form has no errors. Otherwise, False. If errors are
        being ignored, returns False.
        """
#        import ipdb; ipdb.set_trace()
        return self.is_bound and not bool(self.errors)

    def add_prefix(self, field_name):
        """
        Returns the field name with a prefix appended, if this Form has a
        prefix set.

        Subclasses may wish to override.
        """
        return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name

    def render(self, indent_level=0):
        self.content = [] # empty previous content (if render would be called moretimes, there would be multiple forms instead one )
        self.add(self.layout_class(self))
        return super(BaseForm, self).render(indent_level)

    def non_field_errors(self):
        """
        Returns an ErrorList of errors that aren't associated with a particular
        field -- i.e., from Form.clean(). Returns an empty ErrorList if there
        are none.
        """
        result = self.errors.get(NON_FIELD_ERRORS, None)
        if not result:
            result = self.errors[NON_FIELD_ERRORS] = self.error_class()
        return result

    def is_empty(self, exceptions=None):
        """
        Returns True if this form has been bound and all fields that aren't
        listed in exceptions are empty.
        """
        # TODO: This could probably use some optimization
        exceptions = exceptions or []
        for name, field in self.fields.items():
            if name in exceptions:
                continue
            # value_from_datadict() gets the data from the dictionary.
            # Each widget type knows how to retrieve its own data, because some
            # widgets split data over several HTML fields.
            # HACK: ['', ''] and [None, None] deal with SplitDateTimeWidget. This should be more robust.
            if field.value not in (None, '', ['', ''], [None, None]):
                return False
        return True

    def full_clean(self):
        """
        Cleans all of self.data and populates self._errors and
        self.cleaned_data.
        """
        self._errors = ErrorDict()
        if not self.is_bound: # Stop further processing.
            return
        self.cleaned_data = {}
        if self.empty_permitted and not self.has_changed():
            self.cleaned_data = None
            return
        for name, field in self.fields.items():
            self.clean_field(name, field)
        try:
            self.cleaned_data = self.clean()
        except ValidationError, e:
            self._errors[NON_FIELD_ERRORS] = e.messages
        if self._errors:
            delattr(self, 'cleaned_data')