Create model just for testing - django

I have an abstract User model.
The tests include subclassing this abstract model and setting AUTH_USER_MODEL to the subclassed model.
The problem with AUTH_USER_MODEL is it must be of the form "app-name.model-name" and hence it must
refer to a model in a models.py file . But if it is inside a models.py file, it will get sync'ed to production database, which isn't exactly harmful but it would be nice if it isn't so.
I have seen Django: How to create a model dynamically just for testing but the answers seem hackish (and unreliable?)
Currently what I do is:
in [apps]/models.py:
# this model only gets created during a test
if 'test' in sys.argv:
class AccountTest(AbstractAccount):
pass
in [apps]/tests/init.py:
#override_settings(
AUTH_USER_MODEL = '[apps].AccountTest',
)
class AccountManagerTest(TransactionTestCase):
Does anyone have a better way? This feels rather hackish.
Also, any problem with this approach?

A good approach is to use separate settings file for your testing environment. You could have an application that is listed only in the INSTALLED_APPS of these test settings, and implement your test models there. This approach is also good if for example you want to use nose to run your tests etc... Then you should run your tests like this:
python manage.py test --settings=my_project.test_settings

Related

Django best practice: Should I split non-app specific models into my project folder?

I am going to extend the django user models - is it best practice to create a new models.py in my project directory: I.e:
project
application
migrations
static
models.py (all my application specific models)
project
forms.py
urls.py
views.py
*** project models.py ? ***
I want to add email confirmation to my user sign up. So basically just extend the user model. I am thinking this may not be best practice to do in my application models, but for this case it is only going to be one model so would not really matter. However if I want to extend more non-application specific models then it might be better to do this in a separate file?
Does anyone do anything similar and have any tips? Thanks
I don't think putting model inside the project is a food idea, but its practical possible.
For your case I would create an app called utils and put those models there. In real sense i don't think there is non-app specific model . . . correct me if I am wrong.
Plus you can have as many apps as you want
Also you can check post for more

South custom models location

I have quite a big django project which has a lot of applications and a lot of models.
In order to avoid circular imports several models modules must be used:
app/models.py
app/models_add.py
app/models_aux.py
and so on.
Each time I have to make a migration I have to write
from app.models_add import Model
in the app/models.py in order for South to track the model's changes.
This seems to be quite annoying because there are a lot of changes in models.
The question is: is there a way to point South which modules/files to track?
You could try setting the app_label on the Meta class of your model.
class Meta:
app_label = "app"
Also try setting your directory structure to:
app/models/__init__.py
app/models/add.py
That should tell everything to initialize properly. This is what I recently did, but for backwards compatibility in other areas of my project I import everything in models/__init__.py

How to write unit tests for a new third-party Django library

I am making a library as a Django app that's meant to provide generic leaderboards for other apps' models in a game application I'm working on. Clients of my library should extend an abstract base class I'm creating and override methods to provide the code to actually aggregate objects.
I want to keep this charts app self-contained and loosely coupled so that I can easily spin it off and open-source it, and so I'm trying to write unit tests that don't depend on any models in outside apps, even though the whole purpose of the app is to essentially aggregate data from models in outside apps. I could just make a dummy model in the app's own models.py, but then this would cause an unused table to be created for every project that uses the library, which seems non-ideal. Is there an ideal way to do this?
So far, I can see two options.
Option 1: Create unmanaged model classes, and in the tests, create and destroy the database tables manually.
Option 2 (what I chose): Declare test models in my tests module. Follow the advice here and trigger syncdb in the test setUp method to create the tables. Adapted for testing, here's what it looks like:
from django.core.management import call_command
from django.db import models
from django.test import TestCase
class TestModel(models.Model):
data = models.FloatField()
class Meta:
app_label = 'myapp'
class LibraryTests(TestCase):
def setUp(self):
super(LibraryTests, self).setUp()
models.register_models('myapp', TestModel)
call_command('syncdb')

How to test Django custom model fields?

I am thinking of creating some subclassed Django model fields and distributing them as a package on PyPI. I like to write unit tests for my code (à la TDD), but I'm a bit puzzled as to how I'd write tests for this particular library.
The first thought that came to my mind was to create a Django project that makes use of my subclasses and just use the Django test tools, but that doesn't seem very elegant at all. There's got to be a better way!
Is there a method of somehow bootstrapping Django for this type of thing? I'd appreciate someone pointing me in the right direction. Thanks!
Django itself comes with some tests for field-subclassing; the tests have their own models.py where the custom fields are used. You should get the best impression when you have a look at the actual code yourself!
Addition: To have the models defined in your test package being discovered by django you will have to add your yourapp.test package to INSTALLED_APPS.
Django itself has a built-in mechanism for its own tests to be automatically discovered and added to INSTALLED_APPS.

How to override models defined in installed apps in Django?

Is it possible to redefine a model used in an INSTALLED_APP without modifying the app in question? For example, django-basic-blog has a Post model which I would like to add a field to. I could edit django-basic-blog directly but for code portability I'd like to build on top of it. I don't want to subclass as I want to preserve all existing references to the Post model. Thanks in advance!
If you subclass the original fields will be still stored in the original table, so references would stay valid.
If you want to monkey-patch an existing class, which is mostly not the recommendable dirty method, you could use contribute_to_class in some models.py file that will be loaded in an app after the one you want to modify:
models.py:
from django.db.models import CharField
from blog.models import Post
CharField(max_length="100").contribute_to_class(Post, 'new_field')
If you do it like this, you always have to bare the risk that your changes can clash with other pieces of code and that your code will be harder to maintain!