class Template (models.Model):
     tag = models.SlugField (max_length = 16, unique = True)
     title = models.CharField (max_length = 50)
    
     def fields (self):
         return TemplateField.objects.filter (template = self) .order_by ('tab')
     def __unicode __ (self):
         return self.title
 class TemplateField (models.Model):
     FieldTypes = (('T', 'Text'), ('B', 'Bool'), ('E', 'E-mail'), ('U', 'URL'), ('C', 'Choices'),)
     template = models.ForeignKey (Template)
     tag = models.SlugField (max_length = 32)
     title = models.CharField (max_length = 50)
     type = models.CharField (max_length = 1, choices = FieldTypes)
     tab = models.IntegerField (default = 0)
     required = models.BooleanField (default = True)
     def __unicode __ (self):
         return u '% s:% s'% (self.template, self.tag)
     def parameters (self):
         return FieldParameter.objects.filter (field = self) .order_by ('tab')
        
     class Meta:
         unique_together = ("template", "tag")
        
 class FieldParameter (models.Model):
     field = models.ForeignKey (TemplateField)
     tag = models.SlugField (max_length = 32)
     value = models.CharField (max_length = 255)
     tab = models.IntegerField (default = 0)
     def __unicode __ (self):
         return u '% s:% s =% s'% (self.field, self.tag, self.value)
        
     class Meta:
         unique_together = ("field", "tag", "value")
 class Record (models.Model):
     template = models.ForeignKey (Template)
     dt = models.DateTimeField ()
    
     def __unicode __ (self):
         return u '% s @% s'% (self.template, self.dt)
 class RecordData (models.Model):
     record = models.ForeignKey (Record)
     field = models.ForeignKey (TemplateField)
     value = models.CharField (max_length = 255)
    
     def __unicode __ (self):
         return u '% s% s'% (self.record, self.field)
        
     class Meta:
         unique_together = ("record", "field")
 class CDBForm (forms.Form):
     def __init __ (self, template = None, tag = None, * args, ** kwargs):
         if template:
             self.template = template
         elif tag:
             self.template = Template.objects.get (tag = tag)
         fields = self.template.fields ()
         for field in fields:
             if field.type == "B":
                 self.base_fields [field.tag] = forms.BooleanField (label = field.title, required = field.required)
             elif field.type == "T":
                 self.base_fields [field.tag] = forms.CharField (label = field.title, required = field.required)
             elif field.type == "C":
                 choices = []
                 for parameter in field.parameters ():
                     if parameter.tag == "choice":
                         choices.append ((parameter.value, parameter.value))
                 self.base_fields [field.tag] = forms.ChoiceField (choices = choices, label = field.title, required = field.required)
             elif field.type == "E":
                 self.base_fields [field.tag] = forms.EmailField (label = field.title, required = field.required)
             elif field.type == "U":
                 self.base_fields [field.tag] = forms.URLField (label = field.title, required = field.required)
         forms.Form .__ init __ (self, * args, ** kwargs)
     def save (self, commit = True):
         data = self.cleaned_data
         if commit:
             rec = Record (template = self.template, dt = datetime.now ())
             rec.save ()
             for k, v in data.iteritems ():
                 f = TemplateField.objects.get (template = self.template, tag = k)
                 d = RecordData (record = rec, field = f, value = v)
                 d.save ()
         return data
Source: https://habr.com/ru/post/46845/
All Articles