Как добавить новые строки и столбцы в таблицу с помощью 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 также может быть полезен.

Вернуться на верх