Advice on architecture for storing some trivial values in Django database?
I'd like to store some trivial values for each user in the database, like if the user can see the new comers' banner, the instruction on how to use each of the features etc. The number of values can increase as we come across new ideas.
So I've thought about two solutions for storing these data. Either having a field for each of these values (So the structure of the table will change a few times at least), or have one field for all these types of data, so they're stored as a dictionary in the field (In this case, I'm worried about if it's hurting db performance, I also need to write more logics for parsing the dictionary in string and the way around, and if storing dictionaries in db contradicts with what db does).
models.py
class Instruction(models.Model): user=models.ForeignKey('auth.User') can_see_feature_foo_instruction=models.BooleanField() can_see_feature_bar_instruction=models.BooleanField() ...
or
class Instruction(models.Model): user=models.ForeignKey('auth.User') instruction_prefs=models.CharField() #Value will be "{'can_see_foo_inst':True, 'can_see_bar_inst':False, ...}"
Which will be the best solution?
Answers
It depends if you need to be able to search on these fields. If so, the text field option is not really suitable, as the individual flags won't be indexed. But if not, then this is a perfectly good way of going about it. You might want to consider storing it as JSON, which is useful as a method of serializing dicts objects to text and getting them back. There are plenty of implementations around of "JSONField" in Django that will take of serializing/deserializing the JSON for you.
Django has a built-in permission system. Try reading this link https://docs.djangoproject.com/en/dev/topics/auth/#permissions
Update I think if you really want to use an Instruction model. You can use something like a JSONField and use it to store instructions. This way you can do something like instruction.key to access a value. You can try using this. https://github.com/derek-schaefer/django-json-field
You can create model for key value pair of instructions/permissions per user. E.g.
class Instruction(models.Model): user=models.ForeignKey('auth.User') key = models.CharField(max_length=20) value = models.BooleanField()
Then you can create multiple instances of this for each user depending upon permissions he has.
>>>> instr1 = Instruction() >>>> instr1.user = user1 >>>> instr1.key = 'can_see_feature_foo' >>>> instr1.value = True >>>> instr1.save() >>>> instr2 = Instruction() >>>> instr2.user = user1 >>>> instr2.key = 'can_see_feature_bar' >>>> instr2.value = True >>>> instr2.save() .... #To query >>>> Instructions.filter(user=user1, key='can_see_feature_bar')
If you use a Model with a CharField to store the instruction and a ManyToManyField to the users you can create and assign any number of instructions to any number of users.
class Instruction(models.Model): user = models.ManyToManyField('auth.User') instruction = models.CharField() # Value will be a single instruction