Sean
Sean

Reputation: 1159

Altering a Django model's method requires migration?

Does altering an instance method for a model in an app in Django 1.5 require a migration via South?

My understanding is that you cannot serialize random Python code... Moreover, I understand that migrations are really meant to manage changes to table schema--like the addition of an attribute or field for records in the table...or to manage changes to the type of data itself (like upgrading plaintext passwords to hashed / salted passwords).

So--IF there is NO change made directly to a model's attributes, and/or no changes to a specific field type or whatever--THEN a migration is NOT necessary, correct?

And--in general--is it safe to assume changes to instance methods and/or even static methods in a Django model do NOT require a migration?

(Presently, I think it does not. Double checking my thinking here via Stackoverlow.)

What about: changes to a model manager? That is: to a method which impacts an object's instantiation?

Specifically...in regard to the first part of my question about altering an "instance method"...in this case, the model subclasses another custom model, and I want to change some code within the subclassing model, like so:


class Enrollment(ApiModel):

    # init method, etc., in here

    def pretty_semester(self):
        try:
            sem = self.enrollment_dict.get('CourseSemester', 'No Semester')
            if not sem:

                (...) 

                if results:

                    (...)

                elif 'MTS' in sem:
                    results = re.findall(compiled_mts_match, sem)
                    if results:
                        base_string = "Other B 20"
                        if len(results[0]) == 2:
                            if results[0][1] == '02':
                                base_string = 'Winter B 20'
                            elif results[0][1] == '04':
                                base_string = 'Spring B 20'
                            elif results[0][1] == '07':
                                base_string = 'Summer B 20'
                            elif results[0][1] == '08':
                                base_string = 'Summer B 20'
                            elif results[0][1] == '10':
                                base_string = 'Fall B 20'
                        return '%s%s' % (base_string, results[0][0])

                    (...)

            return sem
        except:
            return sem

If I alter only one elif statement in the "pretty semester" method in the above class like so...


    def pretty_semester(self):
        try:
            sem = self.enrollment_dict.get('CourseSemester', 'No Semester')
            if not sem:

                (...) 

                if results:

                    (...)

                #super minor alteration of this elif statement...
                elif 'MTS' in sem:
                    results = re.findall(compiled_mts_match, sem)
                    if results:
                        base_string = "Other B 20"
                        if len(results[0]) == 2:
                            if results[0][1] == '02':
                                base_string = 'Winter B 20'
                            elif results[0][1] == '03':       # new line
                                base_string = 'Spring B 20'   # new line
                            elif results[0][1] == '04':
                                base_string = 'Spring B 20'
                            elif results[0][1] == '07':
                                base_string = 'Summer B 20'
                            elif results[0][1] == '08':
                                base_string = 'Summer B 20'
                            elif results[0][1] == '10':
                                base_string = 'Fall B 20'
                        return '%s%s' % (base_string, results[0][0])

                    (...)

            return sem
        except:
            return sem

...then would this even require a migration?

(NO...it would not, correct?)

(Now if I were tweaking a custom model manager...then??)

Basically, in addition to insight with regard to the example above, I'm seeking some clear and simple rules of thumb for--when hacking on a model--a migration is required...if any such tips can be generalized. I know, too, that there have been some significant changes in how migrations are handled in Django 1.7, but--in this case--I'm using version 1.5.

Upvotes: 4

Views: 3335

Answers (2)

Kevin Christopher Henry
Kevin Christopher Henry

Reputation: 48982

The "clear and simple rule" here is that a South migration is only needed if the change you've made will affect the database schema. (I'm leaving aside data migrations here, where you're explicitly changing the data that's currently in the database. The answer is also different for Django's built-in migrations in 1.7+.)

So your intuition above is correct—nothing you've described should require a migration.

To take an example, let's say you add blank=True to a field. blank affects the way Django validates forms, it doesn't mean anything at the database level. Therefore, that change would not require a migration.

By contrast, null=True is represented at the database level, and therefore would require a migration.

So to really understand when a migration is necessary you have to know something about how databases work. The good news, though, is that South is quite good at automatically detecting whether migrations are necessary or not. So to test your intuition, just do an automatic migration and see what South has to say.

Upvotes: 3

davko
davko

Reputation: 459

Breaking this out into multiple questions:

  1. Does changing a model's instance or static method require a migration: NO
  2. Does adding/changing a model manager require a migration: NO

As a general rule, a migration is only needed when you are changing the structure or integrity of a DB table. None of this happens with model methods or managers.

Upvotes: 2

Related Questions