tickets_full: 91

This data as json

id created changetime last_pulled_from_trac stage status component type severity version resolution summary description owner reporter keywords easy has_patch needs_better_patch needs_tests needs_docs ui_ux
91 2005-07-19 21:45:54 2007-07-03 23:05:24 2019-06-24 00:16:15.030115 Accepted closed Core (Other) enhancement normal   duplicate A (possible) cleaner ORM fields description Here is a cleaner approach to the ORM fields. Using this patch, the example in the tutorial can be changed to this: {{{ from django.core.meta import Model # Create your models here. class Poll(Model): def fields(Field): Field.Char('question', maxlength=200) Field.DateTime('pub_date', 'date published') class Choice(Model): def fields(Field): Field.ForeignKey(Poll) Field.Char('choice', 'choice', maxlength=200, core=True) Field.Integer('votes', 'votes', core=True) }}} I have done an implementation, which is fully backwards compatible, and quite simple. {{{ Index: django/core/ =================================================================== --- django/core/ (revision 227) +++ django/core/ (working copy) @@ -377,12 +377,53 @@ new_v.func_globals[k] = func new_functions[k] = func + +class FieldGenerator(object): + """FieldGenerator is used for... uh... Generating fields. It has attributes, + such as "Char" and "DateTime", that can be used to create class instances such as + "CharField" or "DateTimeField". These instances are then added to the list "fields", + which can be retrieved to be used as the "fields" attribute in a Model class.""" + def __init__(self): + self.fields = [] + self.last_class = None #This is the class obj that corrisponds to the last __getattr__ call. + + def __getattr__(self,name): + self.last_class = None + try: + obj = eval(name+"Field") + if issubclass(obj,Field): self.last_class = obj + except NameError: pass + if not self.last_class: # If name+"Field" didn't work, just try name. + try: + obj = eval(name) + if issubclass(obj,Field): self.last_class = obj + except NameError: pass + if not self.last_class: + raise AttributeError("Could not find either %s or %sField (or they are not decendants of Field.)" % (name,name)) + return self.GenerateField + + def GenerateField(self, *args, **kargs): + """ This creates an instance of the class corrisponding to the + last __getattr__ call, and adds it to self.fields.""" + if not self.last_class: + raise ValueError("GenerateField should only be called with self.last_class set.") + self.fields.append(self.last_class(*args, **kargs)) + self.last_class = None + + class ModelBase(type): "Metaclass for all models" def __new__(cls, name, bases, attrs): # If this isn't a subclass of Model, don't do anything special. if not bases: return type.__new__(cls, name, bases, attrs) + + # If 'fields' is callable, we want to call it, passing a FieldGenerator. + if callable(attrs['fields']): + fg = FieldGenerator() + attrs['fields'](fg) + attrs['fields'] = fg.fields # If this model is a subclass of another Model, create an Options # object by first copying the base class's _meta and then updating it }}} I don't know if this is the best way of doing it... but it's out there! adrian mmarshall   0 0 0 0 0 0