How to store arbitrary type values ​​in one Django model?

Say I have an unknown number of questions. For instance:

  • Bright blue [y / n]
  • What date did you give birth [date]
  • What is pi [3.14]
  • What is great intelligence [100]

Now, each of these questions represents a different, but type-specific answer (boolean, date, float, int). Naturally, django can happily deal with them in the model.

class SkyModel(models.Model):
    question = models.CharField("Is the sky blue")
    answer = models.BooleanField(default=False)

class BirthModel(models.Model):
    question = models.CharField("What date were your born on")
    answer = models.DateTimeField(default=today)

class PiModel(models.Model)
    question = models.CharField("What is pi")
    answer = models.FloatField()

But this has an obvious problem in that each question has a specific model, so if we need to add a question later, I have to change the database. Ugh. So, now I want to get a fantasy - how to set up a model where, by converting the type of response, it happens automatically?

ANSWER_TYPES = (
    ('boolean', 'boolean'),
    ('date', 'date'),
    ('float', 'float'),
    ('int', 'int'),
    ('char', 'char'),
)

class Questions(models.model):
    question = models.CharField(()
    answer = models.CharField()
    answer_type = models.CharField(choices = ANSWER_TYPES)
    default = models.CharField()

So, theoretically, this will do the following:

  • , , .
  • , , answer_type. 3.14 float str.

? - ?

!

+3
3

. , CharField getter __builtin__ getattr. ( ):

VALUE_TYPE_CHOICES = (
    ("unicode", "Unicode String"),
    ("int", "Integer"),
    ("bool", "Boolean"),
)

class Setting(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    type = models.CharField(max_length=50, choices=VALUE_TYPE_CHOICES)
    default_value = models.CharField(max_length=127)

def get_setting(user, setting_id):
    profile_setting = #get the user specific setting value here, not relevant
    type = getattr(__builtin__, profile_setting.setting.type)
    if type is bool:
        return type(int(profile_setting.value))
    else:
        return type(profile_setting.value)

: bool('0') True, int bool. , , , ast module literal_eval. , .

+5

, . , , , .

, .

class Questions(models.model):
    question = models.CharField(()
    answer = models.CharField()
    answer_type = models.CharField(choices = ANSWER_TYPES)
    int_answer = models.IntegerField(null=True)
    bool_answer = models.NullBooleanField(null=True)
    ... etc. 

, CharField.

+2

:

def get_converted_answer(self):
  if self.answer_type == 'int':
    return int(self.answer)
  if self.answer_type == 'bool':
    # ...
+2

Source: https://habr.com/ru/post/1742015/


All Articles