Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango dynamic model fields
    text
    copied!<p>I'm working on a <strong>multi-tenanted</strong> application in which some users can define their own data fields (via the admin) to collect additional data in forms and report on the data. The latter bit makes JSONField not a great option, so instead I have the following solution:</p> <pre><code>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 </code></pre> <p>Note how CustomDataField has a ForeignKey to Site - each Site will have a different set of custom data fields, but use the same database. Then the various concrete data fields can be defined as:</p> <pre><code>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'),) </code></pre> <p>This leads to the following use:</p> <pre><code>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? </code></pre> <p>But this feels very clunky, particularly with the need to manually create the related data and associate it with the concrete model. Is there a better approach? </p> <p>Options that have been pre-emptively discarded:</p> <ul> <li>Custom SQL to modify tables on-the-fly. Partly because this won't scale and partly because it's too much of a hack.</li> <li>Schema-less solutions like NoSQL. I have nothing against them, but they're still not a good fit. Ultimately this data <strong>is</strong> typed, and the possibility exists of using a third-party reporting application.</li> <li>JSONField, as listed above, as it's not going to work well with queries.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload