-
Notifications
You must be signed in to change notification settings - Fork 1
Django notes
This page is for notes about Django that are relevant to CoralNet development. This page isn't meant to be a re-wording of the entire Django documentation; its main purpose is to emphasize certain CoralNet-relevant points while offering some additional tips and links. However, in theory, a Django expert could skip this page entirely and just read the CoralNet documentation.
Contents
General info: media, static files
Media can be a very general and confusing term. Here, we'll discuss only the kind of media that MEDIA_ROOT and MEDIA_URL refer to.
Media are user-uploaded files (such as images) or files that are generated from user-uploaded files (such as image thumbnails). In general, if you have a development copy and a production copy of a website, the media are going to differ between the two. This is how media differ from source code files and static files.
Media should be uploaded or generated in the settings.MEDIA_ROOT directory. Since media are never going to be committed to the Git repository, settings.MEDIA_ROOT may be located outside of the repository (but it currently isn't in CoralNet, as of 2012 Oct 9).
Static files are files that:
- Are loaded directly in the user's web browser (unlike server-side code, such as the Python .py files).
- Remain the same between development and production copies (unlike media).
This includes CSS (Cascading Style Sheet) files, JS (JavaScript) files, and image files used for the site design, icons, etc.
Static files can be put in either of two places:
- The /static subdirectory of any of our installed apps.
- Any directory listed in settings.STATICFILES_DIRS (this is mainly used for static files that aren't tied to a particular app).
In order to actually serve static files to users, the static files need to be collected (i.e. copied over) to one place first. This is done differently depending on the value of settings.DEBUG.
- DEBUG == True: static files are automagically collected and served.
- DEBUG == False: static files must be manually collected in one place. To do this, first set settings.STATIC_ROOT to the directory where you want to collect the static files (this directory can be outside of the repository). Then run the command
python manage.py collectstatic
to collect the static files in STATIC_ROOT. You must do this again every time a static file is updated or added.
(TODO: Information about preventing caching of static files)
See CoralNet documentation - Unit tests for additional CoralNet-specific info.
- Django docs - General info, how to write tests, how to run tests, Django-specific tools, Django-specific assert statements
- Python's unittest docs - info about Python unit tests (not specific to Django or web frameworks), general unit test assert statements
- Sample advice on what kind of functionality should be tested: 1 2
- Ensure that the Django MySQL user has all privileges on the test database. For more info, see Setup - MySQL - Create a database and a user.
- By default, settings.DEBUG is set to False for unit tests, even if our settings file specifies it as True. Thus, if you haven't already done so, you should make sure your development copy can run the server with settings.DEBUG == False. This includes making sure static files are collected at settings.STATIC_ROOT; if this is not done, then running any test that uses the Test Client may result in static-file-related errors (such as
The system cannot find the path specified: u'css/master.css'
).
-
manage.py test
- Runs all tests of all apps in settings.INSTALLED_APPS, including third-party apps. Note that running third-party apps' tests is mainly only done to confirm compatibility and correct installation of these apps. In the normal workflow, it is typically only necessary to run tests for the apps we wrote.- Note: As of 2012 May 14, certain userena tests fail. This appears to be a problem in userena's test code instead of a problem related to CoralNet.
-
manage.py test [appname[.classname[.methodname]]]
- Runs only tests of a specific app, or a specific test class, or a specific test method. Examples:manage.py test images
,manage.py test images.ImageUploadTest
,manage.py test images.ImageUploadTest.test_image_upload_success
- If you use PyCharm, you can do the equivalent of
manage.py test [appname[.classname[.methodname]]]
by right-clicking a test module, class, or method, and then selecting Run 'Test: ...' in the context menu.
Tip: If you're changing the project code, and you find that a test is failing when it didn't before, it can indicate either of two things: (1) You broke some functionality. (2) The functionality has changed and the test needs to be changed to reflect that.
A test class inherits from unittest.TestCase (or a subclass of it, like django.test.TestCase, or BaseTest and ClientTest in lib/test_utils.py).
A single test is a test method within a test class. To specify a test class's test methods, either define a test suite for the class, or don't define a suite and simply prefix each test method's name with test. Read here for more info.
You can specify initial database data for tests by providing fixtures.
- When writing fixtures, try to avoid hard-coding object IDs: specify the pk field as null and use natural keys. This can't always be done, however; for example, IDs will need to be hard-coded for Users and Groups until this Django ticket is accepted and incorporated into a Django release.
- Watch out for [[circular foreign key references in MySQL's InnoDB|http://www.mail-archive.com/[email protected]/msg66968.html]], which is the database engine we use.
- Fixtures can only specify initial database data, not initial files in the filesystem (like initial media, image processing files, etc.). There is no scheme for specifying initial files. (However, CoralNet has a directory for sample files that may be uploaded during tests: settings.SAMPLE_UPLOADABLES_ROOT.)
Tip: Maintain meaningful names for test classes and methods, and whenever possible, maintain large numbers of small test methods instead of small numbers of large test methods. That way, if a test fails, it's easier to tell what kind of test failed.