以下是我开始使用 JSONField(和 PostgreSQL)应对这一挑战的方法。这只是为了给你一个基本的想法,我试着遵循 Django 的原则。前两个简单模型。一种用于存储用户定义的模型定义,另一种用于存储数据。
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)
嗯,这就是我开始工作的方式,不知道我最终会得到什么。当然,我还没有测试过这段代码:)