52

I have a little website with a few users and I'd like to add a field to one of my models (and hence tables.) The problem is that syncdb of course won't touch the existing models and I'm trying to figure out how to add this field to the model/table without having to repopulate the entire thing.

Example:

class Newspaper(models.Model):
    name = models.CharField()

class UserProfile(models.Model):
    user = models.ForeignKey(user, unique=True)
    reads = models.ManyToManyField(Newspaper)

Now I'd like to add a URL field (blank=True) to the Newspaper model without breaking the user profiles.

Any ideas?

Deniz Dogan
  • 25,711
  • 35
  • 110
  • 162

3 Answers3

38

There's no built-in way to do this. However there are a number of third-party projects that will do it for you. The two leading ones are called South and django-evolution, although there are various others as well (including one I've been involved with, dmigrations).

I would definitely recommend South - it has a number of really neat features and works really well.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • I think it's also a good idea to get comfortable altering your databases yourself, especially when it's simple operations like adding a new column or constraint. It's a great way to learn the basics of relationship databases, as well as about the Django ORM. And it's super easy once you know how. – Cody Django Jan 27 '14 at 19:53
  • 4
    could you tell us how? – holmeswatson Jan 28 '14 at 23:09
  • 1
    And years later, South is now part of Django core. – Martijn Pieters Aug 13 '15 at 07:09
18

You could try getting the SQL for your new field using:

manage.py sql appname

Where appname is the name of the application in which your newspaper class lives.

Then, you could manually add a field to your appname_newspaper table, using ALTER TABLE. I'm not aware of a way to do this directly with Django, since Django does not support migrations.

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
  • A small comment: if you go this route, I recommend performing the migration (filling in the initial values of the column) in your Django application, by just looking for uninitialized values and doing it on-the-fly. Trying to fill them in from a different application risks running into issues with caching. – Chiara Coetzee Apr 30 '13 at 02:52
1

2015 answer:

Run the following:

python manage.py makemigrations
python manage.py migrate
User
  • 23,729
  • 38
  • 124
  • 207