Ejemplo n.º 1
0
    def serialize_filters(self, list_filter, queryset):
        filters_list = []
        model = queryset.model

        #configure the filters
        for column_name in list_filter:
            field = get_lookup_field(model, column_name)

            if field is None: continue

            field_type = 'combo'
            field_properties = {
                'field_type': 'combo',
                'label': get_lookup_verbose_name(model, column_name),
                'column': column_name
            }

            if isinstance(field, models.BooleanField):
                field_properties.update({
                    'items': [("{0}=true".format(column_name), 'True'),
                              ("{0}=false".format(column_name), 'False')]
                })

            if isinstance(field, models.Field) and field.choices:
                field_properties.update({
                    'items': [("{0}={1}".format(column_name, c[0]), c[1])
                              for c in field.choices]
                })

            elif isinstance(field, (models.DateField, models.DateTimeField)):
                field_properties.update(
                    self.get_datetimefield_options(column_name))

            elif field.is_relation:
                objects = field.related_model.objects.all()

                limit_choices = field.get_limit_choices_to()
                if limit_choices:
                    objects = objects.filter(**limit_choices)

                filter_values = [(column_name + '=' + str(o.pk), o.__str__())
                                 for o in objects]
                field_properties.update({'items': filter_values})

            else:
                column_values = queryset.values_list(
                    column_name, flat=True).distinct().order_by(column_name)
                filter_values = [(column_name + '=' + str(column_value),
                                  column_value)
                                 for column_value in column_values]
                field_properties.update({'items': filter_values})

            filters_list.append(field_properties)

        return filters_list
Ejemplo n.º 2
0
    def save_object(self, obj):
        """
        Function called to save the object

        :param django.db.models.Model obj: Object to save.
        
        """
        try:
            obj.full_clean()
        except ValidationError as e:
            html = '<ul class="list">'
            for field_name, messages in e.message_dict.items():

                try:
                    getattr(self, field_name).error = True

                    label = get_lookup_verbose_name(self.model, field_name)
                    html += '<li><b>{0}</b>'.format(label.capitalize())
                    field_error = True

                except FieldDoesNotExist:
                    field_error = False
                except AttributeError:
                    field_error = False

                if field_error: html += '<ul>'
                for msg in messages:
                    html += '<li>{0}</li>'.format(msg)
                if field_error: html += '</ul></li>'

            html += '</ul>'
            self.alert(html)
            return None

        obj.save()
        return obj
Ejemplo n.º 3
0
    def serialize(self, init_form=False):
        data = ControlBase.serialize(self)
        queryset = self.value

        rows = []

        if self._update_list and queryset:
            row_start = self.rows_per_page * (self._current_page - 1)
            row_end = self.rows_per_page * (self._current_page)
            model = queryset.model

            if len(self.sort_by) > 0:
                for sort in self.sort_by:
                    direction = '-' if sort['desc'] else ''
                    queryset = queryset.order_by(direction + sort['column'])

            # if no order by exists add one, to avoid the values to be show randomly in the list
            order_by = list(queryset.query.order_by)
            if 'pk' not in order_by or '-pk' not in order_by:
                order_by.append('-pk')
                queryset = queryset.order_by(*order_by)

            rows = self.queryset_to_list(queryset, self.list_display,
                                         row_start, row_end)

            if init_form:
                filters_list = self.serialize_filters(self.list_filter,
                                                      queryset)
                data.update({'filters_list': filters_list})

        if init_form and self.list_display:
            #configure the headers titles
            headers = []
            for column_name in self.list_display:
                label = get_lookup_verbose_name(queryset.model, column_name)

                headers.append({'label': label, 'column': column_name})
            data.update({
                'horizontal_headers': headers,
            })

        if len(self.search_fields) > 0:
            data.update({
                'search_field_key':
                self.search_field_key
                if self.search_field_key is not None else ''
            })

        total_rows = queryset.count()
        total_n_pages = (total_rows / self.rows_per_page) + (0 if (
            total_rows % self.rows_per_page) == 0 else 1)

        data.update({
            'filter_by': self.filter_by,
            'sort_by': self.sort_by,
            'pages': {
                'current_page': self._current_page,
                'pages_list': self.__get_pages_2_show(queryset)
            },
            'pages_total': total_n_pages,
            'value': '',
            'values': rows,
            'values_total': total_rows,
            'selected_row_id': self._selected_row_id
        })

        return data
Ejemplo n.º 4
0
    def create_model_formfields(self):
        """
        Create the model edition form.
        """
        fields2show = self.get_visible_fields_names()
        formset = []

        for field_name in fields2show:

            # if the field already exists then ignore the creation
            if hasattr(self, field_name): continue

            try:
                field = self.model._meta.get_field(field_name)
            except FieldDoesNotExist:
                try:
                    field = getattr(self.model, field_name)
                except AttributeError:
                    continue

            pyforms_field = None

            if not (callable(field) and not isinstance(field, models.Model)):
                label = get_lookup_verbose_name(self.model, field_name)

            if callable(field) and not isinstance(field, models.Model):
                label = getattr(field, 'short_description') if hasattr(
                    field, 'short_description') else field_name
                pyforms_field = ControlText(label.capitalize(), readonly=True)
                self._callable_fields.append(field_name)

            elif field.name in self.readonly:

                if isinstance(field, models.TextField):
                    pyforms_field = ControlTextArea(label.capitalize(),
                                                    readonly=True)
                else:
                    pyforms_field = ControlText(label.capitalize(),
                                                readonly=True)

            elif isinstance(field, models.AutoField):
                pyforms_field = ControlText(label.capitalize(), readonly=True)
                self._auto_fields.append(field_name)

            elif isinstance(field, models.Field) and field.choices:
                pyforms_field = ControlCombo(label.capitalize(),
                                             items=[(c[1], c[0])
                                                    for c in field.choices])
            elif isinstance(field, models.BigIntegerField):
                pyforms_field = ControlInteger(label.capitalize())
            elif isinstance(field, models.BooleanField):
                pyforms_field = ControlCheckBox(label.capitalize())
            elif isinstance(field, models.DateTimeField):
                pyforms_field = ControlDateTime(label.capitalize())
            elif isinstance(field, models.DateField):
                pyforms_field = ControlDate(label.capitalize())
            elif isinstance(field, models.DecimalField):
                pyforms_field = ControlFloat(label.capitalize())
            elif isinstance(field, models.FileField):
                pyforms_field = ControlFileUpload(label.capitalize())
            elif isinstance(field, models.FloatField):
                pyforms_field = ControlFloat(label.capitalize())
            elif isinstance(field, models.ImageField):
                pyforms_field = ControlFileUpload(label.capitalize())
            elif isinstance(field, models.IntegerField):
                pyforms_field = ControlInteger(label.capitalize())
            elif isinstance(field, models.TextField):
                pyforms_field = ControlTextArea(label.capitalize())
            elif isinstance(field, models.NullBooleanField):
                pyforms_field = ControlCombo(label.capitalize(),
                                             items=[('Unknown', None),
                                                    ('Yes', True),
                                                    ('No', False)])
            elif isinstance(field, models.ForeignKey):
                url = "/pyforms/autocomplete/{app_id}/{field_name}/{{query}}/".format(
                    app_id=self.uid, field_name=field.name)
                pyforms_field = ControlAutoComplete(label.capitalize(),
                                                    items_url=url,
                                                    model=field.related_model)

            elif isinstance(field, models.ManyToManyField):
                url = "/pyforms/autocomplete/{app_id}/{field_name}/{{query}}/".format(
                    app_id=self.uid, field_name=field.name)
                pyforms_field = ControlAutoComplete(label.capitalize(),
                                                    items_url=url,
                                                    model=field.related_model,
                                                    multiple=True)
            else:
                pyforms_field = ControlText(label.capitalize())

            # add the field to the application
            if pyforms_field is not None:
                setattr(self, field_name, pyforms_field)
                formset.append(field_name)
                self.edit_fields.append(pyforms_field)

        #Create the inlines edition forms.
        self.inlines_controls_name = []
        self.inlines_controls = []
        for inline in self.inlines:
            pyforms_field = ControlEmptyWidget()
            pyforms_field.name = inline.__name__
            pyforms_field._parent = self
            setattr(self, inline.__name__, pyforms_field)
            self.inlines_controls_name.append(inline.__name__)
            self.inlines_controls.append(pyforms_field)

        self.formset = self.fieldsets if self.fieldsets else formset
        self.formset = self.formset + self.get_buttons_row()
Ejemplo n.º 5
0
    def save_event(self):
        """
        Function called when the save is called.

        Returns:
            :django.db.models.Model object: Created object or None if the object was not saved with success.
        """
        fields2show = self.get_visible_fields_names()

        try:
            obj = self.model_object

            ## create an object if does not exists ####
            if obj is None:
                #check if it has permissions to add new registers
                if ( self.parent and hasattr(self.parent, 'has_add_permission') ) and \
                   not self.parent.has_add_permission():
                    raise Exception(
                        'Your user does not have permissions to add')

                obj = self.create_newobject()
            ###########################################

            # if it is working as an inline edition form #
            if self.parent_field:
                setattr(obj, self.parent_field.name,
                        self.parent_model.objects.get(pk=self.parent_pk))
            ##############################################

            for field in self.model._meta.get_fields():
                if field.name not in fields2show: continue
                if field.name in self.readonly: continue

                pyforms_field = getattr(self, field.name)
                value = pyforms_field.value

                if isinstance(field, models.AutoField):
                    continue

                elif isinstance(field, models.FileField):
                    getattr(self, field.name).error = False
                    value = getattr(self, field.name).value
                    if value:
                        try:
                            os.makedirs(
                                os.path.join(settings.MEDIA_ROOT,
                                             field.upload_to))
                        except os.error as e:
                            pass

                        paths = [p for p in value.split('/') if len(p) > 0][1:]
                        from_path = os.path.join(settings.MEDIA_ROOT, *paths)
                        if os.path.exists(from_path):
                            to_path = os.path.join(settings.MEDIA_ROOT,
                                                   field.upload_to,
                                                   os.path.basename(value))
                            os.rename(from_path, to_path)

                            url = '/'.join([field.upload_to] +
                                           [os.path.basename(value)])
                            if url[0] == '/': url = url[1:]
                            setattr(obj, field.name, url)
                    elif field.null:
                        setattr(obj, field.name, None)
                    else:
                        setattr(obj, field.name, '')

                elif isinstance(field, models.ForeignKey):
                    if value is not None:
                        try:
                            value = field.related_model.objects.get(pk=value)
                        except:
                            self.alert('The field [{0}] has an error.'.format(
                                field.verbose_name))
                            pyforms_field.error = True
                    else:
                        value = None
                    setattr(obj, field.name, value)

                elif not isinstance(field, models.ManyToManyField):
                    pyforms_field.error = False
                    setattr(obj, field.name, value)

            try:
                obj.full_clean()
            except ValidationError as e:
                html = '<ul class="list">'
                for field_name, messages in e.message_dict.items():

                    try:
                        getattr(self, field_name).error = True

                        label = get_lookup_verbose_name(self.model, field_name)
                        html += '<li><b>{0}</b>'.format(label.capitalize())

                        field_error = True

                    except FieldDoesNotExist:
                        field_error = False
                    except AttributeError:
                        field_error = False

                    if field_error: html += '<ul>'
                    for msg in messages:
                        html += '<li>{0}</li>'.format(msg)
                    if field_error: html += '</ul></li>'

                html += '</ul>'
                self.alert(html)
                return None

            obj.save()

            for field in self.model._meta.get_fields():

                if isinstance(field, models.ManyToManyField) and hasattr(
                        self, field.name):
                    values = getattr(self, field.name).value
                    field_instance = getattr(obj, field.name)

                    objs = field.related_model.objects.filter(pk__in=values)
                    values_2_remove = field_instance.all().exclude(
                        pk__in=[o.pk for o in objs])

                    for o in values_2_remove:
                        field_instance.remove(o)

                    values_2_add = objs.exclude(
                        pk__in=[o.pk for o in field_instance.all()])
                    for o in values_2_add:
                        field_instance.add(o)

            self.object_pk = obj.pk

            self.update_callable_fields()
            self.update_autonumber_fields()

            return obj

        except Exception as e:
            traceback.print_exc()
            self.alert(str(e))

            return None