1

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 design/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.

1

I may be misunderstanding some details of your question, but I'll try anyway. This is how I would do it:

I would structure App1, App2, etc... as Python packages, and would version these packages to map to App1_v1, App1_v2, App2_v1, etc...

I would then create another package for site.com, and version it to map to site.com/2012, site.com/2013, etc...

All of these packages would be in separate source repositories.

The different versions of the site.com package would depend on the App1_vX, App2_vX packages, at the appropriate versions.

I would then deploy the different versions of site.com to different servers, or at least different virtual environments, as you can't install multiple versions of the same app in the same environment.

I think that would be the cleanest solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.