Поля динамической модели Django
Я работаю надмульти-арендуемых приложение, в котором некоторые пользователи могут определять свои собственные поля данных (через администратора), чтобы собирать дополнительные данные в формах и сообщать о них. Последний бит делает JSONField не лучшим вариантом, поэтому вместо этого у меня есть следующее решение:
class CustomDataField(models.Model):
"""
Abstract specification for arbitrary data fields.
Not used for holding data itself, but metadata about the fields.
"""
site = models.ForeignKey(Site, default=settings.SITE_ID)
name = models.CharField(max_length=64)
class Meta:
abstract = True
class CustomDataValue(models.Model):
"""
Abstract specification for arbitrary data.
"""
value = models.CharField(max_length=1024)
class Meta:
abstract = True
Обратите внимание, что CustomDataField имеет ForeignKey для сайта - каждый сайт будет иметь свой набор настраиваемых полей данных, но использовать одну и ту же базу данных. Тогда различные конкретные поля данных могут быть определены как:
class UserCustomDataField(CustomDataField):
pass
class UserCustomDataValue(CustomDataValue):
custom_field = models.ForeignKey(UserCustomDataField)
user = models.ForeignKey(User, related_name='custom_data')
class Meta:
unique_together=(('user','custom_field'),)
Это приводит к следующему использованию:
custom_field = UserCustomDataField.objects.create(name='zodiac', site=my_site) #probably created in the admin
user = User.objects.create(username='foo')
user_sign = UserCustomDataValue(custom_field=custom_field, user=user, data='Libra')
user.custom_data.add(user_sign) #actually, what does this even do?
Но это выглядит очень неуклюже, особенно из-за необходимости вручную создавать связанные данные и связывать их с конкретной моделью. Есть ли лучший подход?
Варианты, которые были предварительно отброшены:
Пользовательский SQL для изменения таблиц на лету. Отчасти потому, что это не масштабируется, а отчасти потому, что это слишком много для взлома.Решения без схемы, такие как NoSQL. Я ничего не имею против них, но они все еще не подходят. В конечном итоге эти данныеявляется набрано, и существует возможность использования стороннего приложения для создания отчетов.JSONField, как указано выше, не очень хорошо работает с запросами.