TAGS :Viewed: 8 - Published at: a few seconds ago

[ Multiple different versions of similar apps in one project ]

I need some help to improve the architecture of a site I've built. What I want to achieve within a single Django project is the following:

  • I want a site that comes in several versions (one per year), such that each version has a set of apps that are related to that version.
  • I want to keep all the old versions of the site and the state of the apps in that version, but still being able to add/change/remove the apps for any other version. That is, the apps may be different across versions (models, methods, admin, templates, anything basically).

  • I want each app that belongs to a version to have the data for that version only. App1 on version 2012 should have one database table, and App1 on version 2013 should have another, even if they are the same.

It could look something like this:

site.com/2012
    App1_v1
    App2_v1

site.com/2013
    App1_v1
    App2_v2 (maybe added some fields or methods, changed templates)

site.com/2014
    App1_v2
    App2_v2
    App3_v1

My current solution is rather horrible. When a new version of the site is launched, I simply copy-paste an earlier app and have the old app be as it is, and then adding/modifying the new version of the app. But, as I add more apps and more versions come, I get a stupid amount of apps and it feels like bad design.

How can I achieve this in Django in a better way? Or at least, how can I structure it in a better way? I think about having some base model for each app, from which each version then inherits from, but that still makes a lot of apps.

As an example of an app I have, it may look like this:

App name: App_v1_2012

Model

class Bag(models.Model)
    name = models.CharField()

class Item(models.Model)
    name = models.CharField()
    in_bag = models.ForeignKey(Bag)

View

class IndexView(generic.ListView):
    model = Bag
    template_name = 'sometemplate_2012.html'

App name: App_v1_2013

Model

class Bag(models.Model)
    name = models.CharField()

class Item(models.Model)
    name = models.CharField()
    in_bag = models.ForeignKey(Bag)

View

class IndexView(generic.ListView):
    model = Bag
    template_name = 'sometemplate_2013.html'

App name: App_v2_2014

Model

class Bag(models.Model)
    bag_name = models.CharField()
    owner = models.ForeignKey(User)

class Item(models.Model)
    name = models.CharField()
    in_bag = models.ForeignKey(Bag)

View

class IndexView(generic.ListView):
    model = Bag
    template_name = 'sometemplate_2014.html'

As you can see, my biggest problem is the violation of the DRY principle. Everything get copy-pasted, but it's the same information.

Answer 1


Why don't you just import models and views from previous apps, as if they were library functions? You can also inherit from other classes and add methods and attributes, or override them when necessary. Python has lots of OOP tools for these kinds of situations.

Answer 2


I'm not sure if/how django supports symlinks, but if it does a scheme along these lines (I'm using something similar with Google App Engine) would help at least minimizing the number of repos you need to manage and the cloning:

App1_v1
App2_v2
App2_v1
App3_v1
site.com/2012
    App1_v1 -> ../../App1_v1
    App2_v1 -> ../../App2_v1
site.com/2013
    App1_v1 -> ../../App1_v1
    App2_v2 -> ../../App2_v2
site.com/2014
    App1_v1 -> ../../App1_v1
    App2_v2 -> ../../App2_v2
    App3_v1 -> ../../App3_v1