Вот как я бы начал решать эту проблему с использованием JSONField (и PostgreSQL).Это просто чтобы дать вам основную идею, и я попытался следовать принципам Джанго.Первые две простые модели.Один для хранения определений моделей, как определено пользователями, а другой для хранения данных.
models.py
from django.db import models
from django.contrib.postgres.fields import JSONField
from django.utils.text import slugify
class ModelDefinition(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
verbose_name = models.CharField(max_length=50)
name = models.CharField(max_length=50, unique=True)
definition = JSONField()
def save(self, *args, **kwargs):
self.name = slugify(self.verbose_name)
super().save(*args, **kwargs)
class Data(models.Model):
model_definition = models.ForeignKey(ModelDefinition, on_delete=models.CASCADE)
data = JSONField()
Ниже приведен пример того, как вы можете добавлять определения моделей, добавлять и возвращать данные.Я не включил проверку данных, так как мне потребовалось бы не менее часа, чтобы написать код для базовой проверки.
views.py
from .models import ModelDefinition, Data
from django.http import HttpResponse, JsonResponse
def create_model_definition(request):
''' Handles creation of model definitions '''
model_definition = {
'fields': [
{
'name': 'automobile',
'verbose_name': 'Automobile',
'data_type': 'string',
'max_length': 50,
'blank': False,
'null': False
},
{
'name': 'type',
'verbose_name': 'Automobile type',
'data_type': 'string',
'max_length': 20,
'blank': False,
'null': False
},
{
'name': 'doors',
'verbose_name': 'Number of doors',
'data_type': 'integer',
'blank': False,
'null': False
}
],
'global_options': {
'guest': {
'verbose_name': 'Allow guests to enter data',
'option': True
},
'public': {
'verbose_name': 'Data is publicly accessible',
'option': False
}
}
}
ModelDefinition.objects.create(
user=request.user,
verbose_name='My automobiles',
definition=model_definition
)
return HttpResponse('model definition created')
def add_data(request, table='my-automobiles'):
''' Handles data entry '''
model_definition = get_object_or_404(ModelDefinition, user=request.user, name=table)
if not request.user.is_authenticated and not model_definition.definition['global_options']['guest']['option']:
return HttpResponse('Sorry, only authenticated users can enter data')
data_rows = [
{
'automobile': 'Audi',
'type': 'limousine',
'doors': 4
},
{
'automobile': 'Fiat',
'type': 'hatchback',
'doors': 3
},
{
'automobile': 'Iveco',
'type': 'truck',
'doors': 2
}
]
for row in data_rows:
Data.objects.create(
model_definition=model_definition,
data=data
)
return HttpResponse('rows saved')
def show_data(request, table='my-automobiles'):
''' Returns data in JSON format '''
model_definition = get_object_or_404(ModelDefinition, name=table)
if not request.user.is_authenticated and not model_definition.definition['global_options']['public']['option']:
return HttpResponse('Sorry, only authenticated users can view data')
data = Data.objects.filter(model_definition__name=table)
return JsonResponse(data)
Так вот, как бы я начал работать над этим, не знаю, чем я в итоге закончу.Конечно, я не проверял ни один из этого кода:)