Tuesday, October 14, 2014

A few notes when upgrading my Django project to v1.7 from v1.5

Here are something I want to take notes when upgrading my project to the latest version of Django, v1.7 from v1.5.

1. Model Form and Model Formset:

I have to explicitly declare which fields of the model I want to include in or exclude from the form. For example:

# all fields of the model
class MyForm(ModelForm):
class Meta:
model = MyModel
fields = '__all__'

# some fields only
class MyForm(ModelForm):
class Meta:
model = MyModel
fields = ('first_field', 'second_field')

# or exclude these fields
class PtcPeriodForm(ModelForm):
class Meta:
model = PtcPeriod
exclude = ('third_field', 'fourth_field')

# formset
MyFormSetBase = modelformset_factory(
MyModel,
extra=0,
fields = ('first_field','second_field')
)

# inline formset
MyInlineFormSetBase = inlineformset_factory(
MyModel,
MySubModel,
can_delete=True,
fields=('some_field', 'another_field')
)


2. Default test runner:

When I first ran my project with Django 1.7, I got this warning message:

WARNINGS:
?: (1_6.W001) Some project unittests may not execute as expected.
        HINT: Django 1.6 introduced a new default test runner. It looks like this project was generated using Django 1.5 or earlier. You should ensure your tests are all running & behaving as expected. See https://docs.djangoproject.com/en/dev/releases/1.6/#new-test-runner for more information.

Here is what the documentation says:

New test runner

In order to maintain greater consistency with Python’s unittest module, the new test runner (django.test.runner.DiscoverRunner) does not automatically support some types of tests that were supported by the previous runner:
  • Tests in models.py and tests/__init__.py files will no longer be found and run. Move them to a file whose name begins with test.
  • Doctests will no longer be automatically discovered. To integrate doctests in your test suite, follow the recommendations in the Python documentation.
Django bundles a modified version of the doctest module from the Python standard library (in django.test._doctest) and includes some additional doctest utilities. These utilities are deprecated and will be removed in Django 1.8; doctest suites should be updated to work with the standard library’s doctest module (or converted to unittest-compatible tests).
If you wish to delay updates to your test suite, you can set your TEST_RUNNER setting to django.test.simple.DjangoTestSuiteRunner to fully restore the old test behavior. DjangoTestSuiteRunner is deprecated but will not be removed from Django until version 1.8.

So, I have to rewrite my unittest for future compatibility. For now, I just need to put the TEST_RUNNER in my settings.py:

TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner'


3. The TEMPLATE_DIRS setting must be a tuple. So, even your Django project only has one directory that stores template files, you have to put a comma at the end:

TEMPLATE_DIRS = (
      '/path/to/my/templates',
)

4. Applying the Django's migrations to my apps:

* Remove south from INSTALLED_APPS
* Delete all migration files except the __init__.py file and the migrations directory.
* Create a migration for my app ABC:

$ ./manage.py makemigrations myappname

* Then run the migrate command to apply that migration:

$ ./manage.py migrate


Reference: https://docs.djangoproject.com/en/1.7/topics/migrations/

(to be continued...)