views:

47

answers:

3

I am hoping to to build a model for a single table that houses different types of "articles" (for argument's sake).

Each article will have MOSTLY common fields (e.g. title, date etc.) but there are cases where some article types (outside of my control) have slightly different field requirements and respective validation rules . No field will ever hold a particularly large amount of data (~100 char max).

At the moment I'm considering a model that defines all common fields and then has a text field for any unusual fields which can be detailed in XML/JSON:

class Article(models.Model):
    owner = models.ForeignKey('User')
    title = models.CharField(max_length=20)
    published = models.BooleanField()
    extra = model.TextField() # XML/JSON here for any unusual fields
    created = models.DateField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True, auto_now_add=True)
    # ... etc.

I would create django form classes to handle validation as new article types are added but I'm trying to avoid having different tables for different article types.

Is there a commonly accepted way to handle a situation like this or is it largely subjective? Obviously the XML/JSON adds a bit of unfortunate overhead.

Thanks.

A: 

Wouldn't you be able to do this with GenericForeignKeys ?

http://www.djangoproject.com/documentation/models/generic_relations/

You would add a:

extra_type = models.ForeignKey(ExtraType)
extra = generic.GenericForeignKey()

to your model. Seems better than including json.

slurdge
Even `GenericForeignKey` needs another model to point to.
Ignacio Vazquez-Abrams
Thanks for the heads-up, I'll have a look at this.
Thomas Slater
+1  A: 

It's... a pretty awful way to do it. Normally you would put that data into a separate table and relate to it, but... whatever.

XMLField

django-picklefield

Ignacio Vazquez-Abrams
Could you elaborate on "put that data into a separate table and relate to it"? I figure my main problem here is that I won't know what fields to put in that separate table - which brings me back to where I started. That picklefield looks convenient but possibly overkill since additional unknown fields would be the exception rather than the norm. Will check it out.
Thomas Slater
A: 

What I do is create a model that inherits from the Article model.
If you want to create a table for each model just flag abstract = True in your metaclass.
If you want to create a One-To-One relationship with the base Article just make sure abstract = False in your meta class.
Use south to migrate your new models into the database and done.

See this article and this document for more details about model inheritance.

Is there a special reason you need such flexability of fields?
Might they change from within the backoffice?

the_drow
Thanks, an abstract parent class looks promising. I shouldn't have phrased my problem as "articles" so let me try clear it up. My application requires users to save credentials/settings for various payment gateways. Settings vary from gateway to gateway - for example, some gateways have additional credentials for recurring transactions). I'm hoping to develop a system that can add payment gateways as necessary - but still be able to do a simple query to find all gateways by user (i.e. without having to manually run queries against all gateway models. Does that make sense? Any suggestions?
Thomas Slater