Как добавить новые строки и столбцы в таблицу с помощью Django?
Клиент хочет от меня совсем другого. Он хочет иметь возможность создавать таблицу из панели администратора и давать команды этой функции с фронта.
Это команды: При нажатии кнопки ROW будет создана новая строка. При нажатии на кнопку CELL будет создан новый столбец.
Я могу сделать это с помощью JavaScript. Но я не знаю, как сохранить их в базе данных с помощью django. Так как же должна храниться колонка в базе данных, когда она создается? У меня нет идей. Если у вас есть пример кода или идея по этому поводу, пожалуйста, поделитесь со мной. Спасибо.
Я не знаю, работает ли это на самом деле или нет. Общая идея заключается в следующем
создайте форму django с полем (может быть перечислением, чтобы мы могли выбирать соответственно), nullable или not как boolean, max_length если есть, значение по умолчанию если есть, если forms.
А в представлениях генерировать сырой sql и выполнять его.
class DynamicDatabaseForm(forms.Form):
varchar_field_name = forms.CharField()
varchar_max_length = forms.IntegerField()
nullable = forms.BooleanField()
char_field_default = forms.CharField()
# ... other properties
По просмотрам
class DynamicDatabaseFieldAddView(View):
def post(self, request):
table_name = 'user_user' # the name of the database table in which you want to add column
if request.POST.get('field') == 'varchar':
column_type = f"varchar({request.POST['varchar_max_length']})"
if request.POST['nullable']:
sql = f"ALTER TABLE {table_name} ADD {varchar_field_name} {column_type} NULL;"
else:
sql = f"ALTER TABLE {table_name} ADD {varchar_field_name} {column_type} NOT NULL DEFAULT {request.POST['char_field_default']};"
with connection.cursor() as cursor:
cursor.execute(sql)
# other logic
Вы можете использовать JSON-поле для хранения всех строк для всех таблиц. Что-то вроде
class DynamicTableSchema( models.Model):
table_name = models.CharField( max_length= ...)
schema = models.JSONField( ...)
class DynamicTable( models.Model):
table_name = models.CharField( max_length= ...)
# table = models.ForeignKey( 'DynamicTableSchema', ..., related_name='rows', ) # alternative
data = models.JSONField( ...)
schema
будет содержать список допустимых имен столбцов. Вы также можете хранить здесь связанную информацию для проверки, например, что является допустимыми данными, а что - человекочитаемой меткой столбца.
data
будет содержать данные для строк именованной таблицы.
Концептуальные примеры:
table = TableSchema.objects.get( name='MyTable')
print(table.schema)
{ 'quantity':{
'type':'integer',
'default': 0,
'label': 'quantity'
},
'description':{
'type':'string',
'default': None,
'label': 'Item Description',
'max_len': 80
}
}
foo = DynamicTable.objects.filter( table_name='foo').first()
# or using alternative ForeignKey,
# foo = table.rows.first()
print( foo.data)
{
'quantity': 42,
'description': 'Wooly Socks',
}
Если ваша базовая БД - Postgres, то ее возможности по поиску таких данных по кверисету значительны.
Вы будете отвечать за проверку данных пользователя на соответствие схеме (динамически создаваемые формы?) и за вставку значений по умолчанию при создании нового столбца (или неявное создание значения по умолчанию при первом обращении к такому столбцу). Существует довольно тесная связь между form.valid_data
и data
в модели.
Пакет Python Cerberus также может быть полезен.