Example #1
0
def get_columns(request, app_name, model_name):
    '''
    ' Return a HttpResponse with JSON serialized column list for rendering a grid representing a
    ' model.
    '
    ' Keyword args:
    '   app_name   - The application the desired model resides in.
    '   model_name - The name of the model to represent.
    '''

    user = check_access(request)
    if user is None:
        errors = 'User is not logged in properly.'
        return HttpResponse(json.dumps({'errors': errors}, indent=4), content_type="application/json")

    cls = apps.get_model(app_name, model_name)

    filter_depth = None
    if hasattr(cls, 'fk_filter_depth'):
        filter_depth = cls.fk_filter_depth

    return HttpResponse(json.dumps(gen_columns(cls, False, filter_depth), indent=4), content_type="application/json")
Example #2
0
def update(request, app_name, model_name, user, id=None):
    '''
    ' Modifies a model object with the given data, saves it to the db and
    ' returns it as serialized json.
    '
    ' Keyword Args:
    '    model_name  - The name of the model object to modify.
    '    data - The data to modify the object with.
    '
    ' Returns:
    '    The modified object serialized as json.
    '''

    try:
        data = json.loads(request.body)
    except:
        transaction.rollback()
        dump = json.dumps({'errors': 'Error loading json'}, indent=4)
        return HttpResponse(dump, content_type="application/json")

    cls = apps.get_model(app_name, model_name)
    if id is None:
        if not cls.objects.can_edit(user):
            transaction.rollback()
            dump = json.dumps({'errors': 'User %s does not have permission to add to this table.' % str(user)}, indent=4)
            return HttpResponse(dump, content_type="application/json")
        obj = cls()
    else:
        try:
            obj = cls.objects.get_editable_by_pk(user, pk=id)
            if obj is None:
                transaction.rollback()
                dump = json.dumps({'errors': 'User %s does not have permission to edit this object' % str(user)}, indent=4)
                return HttpResponse(dump, content_type="application/json")
        except Exception as e:
            transaction.rollback()
            dump = json.dumps({'errors': 'Cannot load object to save: Exception: ' + e.message}, indent=4)
            return HttpResponse(dump, content_type="application/json")

    try:
        fields = gen_columns(obj)
    except Exception as e:
        transaction.rollback()
        dump = json.dumps({'errors': 'Error generating columns: ' + e.message}, indent=4)
        return HttpResponse(dump, content_type="application/json")

    m2m = []
    try:
        for field in fields:
            if field['_editable']:

                # save inportant m2m stuff for after object save
                if field['_type'] == 'm2m':
                    m2m.append({
                        'field': field['field'],
                        'model_name': field['model_name'],
                        'app': field['app']
                    })
                    continue

                # Handle empy data
                elif data[field['field']] in [None, ''] and field['_type'] != 'password':
                    if field['_type'] in ['text', 'char', 'color']:
                        setattr(obj, field['field'], '')
                    else:
                        setattr(obj, field['field'], None)

                elif field['_type'] == 'foreignkey':
                    rel_cls = apps.get_model(field['app'], field['model_name'])
                    if data[field['field']]['pk'] is None:
                        rel_obj = None
                    else:
                        rel_obj = rel_cls.objects.get(pk=data[field['field']]['pk'])

                    if rel_obj is None or rel_obj.can_view(user):
                        setattr(obj, field['field'], rel_obj)
                    else:
                        transaction.rollback()
                        error = 'Error: You do not have permission to assign this object: %s' % rel_obj
                        return HttpResponse(json.dumps({'errors': error}, indent=4), content_type="application/json")

                elif field['_type'] == 'datetime':
                    dt_obj = None
                    if settings.USE_TZ and data[field['field']] not in (None, u""):
                        dt_obj = make_aware(datetime.utcfromtimestamp(float(data[field['field']])), utc)
                    elif not settings.USE_TZ and data[field['field']] not in (None, u""):
                        aware_dt_obj = make_aware(datetime.utcfromtimestamp(float(data[field['field']])), utc)
                        dt_obj = make_naive(aware_dt_obj, get_current_timezone())

                    setattr(obj, field['field'], dt_obj)

                elif field['_type'] == 'date':
                    dt_obj = datetime.strptime(data[field['field']], settings.D_FORMAT)
                    setattr(obj, field['field'], dt_obj.date())

                elif field['_type'] == 'password':
                    if data[field['field']] not in [None, '']:
                        obj.set_password(data[field['field']])

                else:
                    setattr(obj, field['field'], data[field['field']])
        obj.save()

        try:
            # Get all respective objects for many to many fields and add them in.
            for m in m2m:
                cls = apps.get_model(m['app'], m['model_name'])
                m2m_objs = []
                for m2m_obj in data[m['field']]:
                    rel_obj = cls.objects.get(pk=m2m_obj['pk'])
                    if rel_obj.can_view(user):
                        m2m_objs.append(rel_obj)
                    else:
                        transaction.rollback()
                        error = 'Error: You do not have permission to assign this object: %s' % rel_obj
                        return HttpResponse(json.dumps({'errors': error}, indent=4), content_type="application/json")

                setattr(obj, m['field'], m2m_objs)

        except Exception as e:
            transaction.rollback()
            error = 'Error setting ManyToMany fields: %s: %s' % (type(e), e.message)
            stderr.write(error)
            stderr.flush()
            transaction.rollback()
            return HttpResponse(json.dumps({'errors': error}, indent=4), content_type="application/json")

    except Exception as e:
        transaction.rollback()
        error = 'In ajax update exception: %s: %s\n' % (type(e), e.message)
        stderr.write(error)
        stderr.flush()
        return HttpResponse(json.dumps({'errors': error}, indent=4), content_type="application/json")

    # Run validations
    try:
        obj.full_clean()
    except ValidationError as e:
        transaction.rollback()
        errors = 'ValiationError '
        for field_name, error_messages in e.message_dict.items():
            errors += ' ::Field: %s: Errors: %s ' % (field_name, ','.join(error_messages))

        return HttpResponse(json.dumps({'errors': errors}, indent=4), content_type="application/json")

    try:
        serialized_model = serialize_model_objs([obj.__class__.objects.get(pk=obj.pk)], {'read_only': True})
    except Exception as e:
        transaction.rollback()
        error = 'In ajax update exception: %s: %s\n' % (type(e), e.message)
        stderr.write(error)
        stderr.flush()
        return HttpResponse(json.dumps({'errors': error}, indent=4), content_type="application/json")

    transaction.commit()
    response = HttpResponse(serialized_model, content_type="application/json")
    response.status_code = 201
    return response