On Sat, Mar 16, 2013 at 9:14 PM, Felipe Coelho <fcoelh...@gmail.com> wrote:
> 2013/3/14 Felipe Coelho <fcoelh...@gmail.com> > >> I'm using Django 1.5 and I'm trying to make an application work with >> any custom user model. >> >> The issue is that I want to be able to test the app as well, but I >> can't find a way to make `ForeignKey` model fields to test correctly >> using custom user models. When I run the test case attached below, I >> get this error: >> >> ValueError: Cannot assign "<NewCustomUser: al...@bob.net>": >> "ModelWithForeign.user" must be a "User" instance. >> >> This is the file I'm using for testing: >> >> from django.conf import settings >> from django.contrib.auth import get_user_model >> from django.contrib.auth.tests.custom_user import CustomUser, >> CustomUserManager >> from django.db import models >> from django.test import TestCase >> from django.test.utils import override_settings >> >> class NewCustomUser(CustomUser): >> objects = CustomUserManager() >> class Meta: >> app_label = 'myapp' >> >> class ModelWithForeign(models.Model): >> user = models.ForeignKey(settings.AUTH_USER_MODEL) >> >> @override_settings( >> AUTH_USER_MODEL = 'myapp.NewCustomUser' >> ) >> class MyTest(TestCase): >> user_info = { >> 'email': 'al...@bob.net', >> 'date_of_birth': '2013-03-12', >> 'password': 'password1' >> } >> >> def test_failing(self): >> u = get_user_model()(**self.user_info) >> m = ModelWithForeign(user=u) >> m.save() >> >> I'm referencing the user model in the `ForeignKey` argument list as >> described in >> https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.get_user_model >> , >> but using `get_user_model` there doesn't change anything, as the >> `user` attribute is evaluated before the setting change takes place. >> Is there a way to make this ForeignKey play nice with testing when I'm >> using custom user models? >> > > Since this question didn't get as much love as I expected, let me rephrase > it: > > Is is possible to drop and recreate specific database tables during > testing? That would allow me to alter the model with the offending > ForeignKey, recreate the table and use it during testing. The database > content is already flushed between tests, so if I group the tests in a good > way I hope that the overhead of a drop/create table will not be as heavy as > it would be. > Essentially, no -- at least, not out of the box. You might be able to rig together some setUp() and tearDown() calls that invoke the table creation code that Django executes as part of syncdb, but I can't point you at a simple example of working code or anything like that. Internally, Django has avoided this sort of problem in three ways: 1) Using tests that need the models, but don't actually touch the database. This means you can put the model definition inline in the test code, so AUTH_USER_MODEL has the right value when the code is run. This lets us test validation conditions, etc, but not hit the database. You *might* be able to get away with manually running syncdb in the middle of the test -- Django's swappable_model test contains an example of doing this, but only for the purposes of recreating permissions, not tables. 2) Define 2 "ModelWIthForeign" classes, and use the "right" one depending on what the User model is at the time of test. This works fine for Django's purposes because "ModelWithForeign" is a test-only model, so it doesn't matter if you have a few of them. This approach won't be successful if you're actually shipping ModelWithForeign as a core part of your system. 3) Use test decorators to skip the test if a non-default user model is in use. Any suggestions on how to improve Django's testing infrastructure to handle custom User models would be gratefully accepted (especially if they come with patches). It's still new code, so reports of problems like yours are helpful in shaping what features we've missed during initial development. Yours, Russ Magee %-) -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at http://groups.google.com/group/django-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.