I'm currently writing the tests for our django application. Sadly we had to use a multiple database layout and can't change this. (Distributed databases with multiple backends on different servers across multiple datacenters)
We have two databases:
For these models we wrote different routers like documented on the django site. Now the problem, if I run python manage.py test customerreceipts the test framework dies after some seconds with the following error:
django.db.utils.ProgrammingError: relation "auth_user" does not exist
I checked the created database and there were no tables. Because of this a query from a model throws the error.
The problem model is (in database 2):
class CustomerReceipts(models.Model):
def _choices_user():
users = User.objects.all()
users = users.order_by('id')
return [(e.id, e.username) for e in users]
# General
receipt_name = models.CharField(max_length=20, verbose_name="Receipt name") #: Receipt name
....
# Auditing
owner = models.IntegerField(verbose_name="Owner", choices=[('', '')] + _choices_user())
Because multiple database setup does not support direct links, we use an IntegerField for the owner and the business logic handles the integrity.
The problem is the _choices_user() which sets up an query for the missing table. What I don't understand is why django does not create the table auth_user in the first run. If I remove the app with the causing model, the test framework is working without any problem.
Any ideas how this can be fixed?
Thanks!
Edit: I created a one database setup and tried the same thing. Sadly it throws the same error! I'm confused now. Can someone test this too? Create a model with _choices_user method and run test.
This is not exactly a perfect answer but the only way currently:
Model (removed choices):
class CustomerReceipts(models.Model):
# General
receipt_name = models.CharField(max_length=20, verbose_name="Receipt name") #: Receipt name
....
# Auditing
owner = models.IntegerField(verbose_name="Owner")
Admin:
class CustomerReceiptsAdminForm(forms.ModelForm):
class Meta:
model = CustomerReceipts
users = forms.ChoiceField()
def __init__(self, *args, **kwargs):
super(CustomerReceiptsAdminForm, self).__init__(*args, **kwargs)
owner = self.instance.owner
usersAll = User.objects.all()
usersAll = usersAll.order_by('id')
available_choices = [(e.id, e.username) for e in usersAll]
self.fields['users'].choices = available_choices
self.fields['users'].initial = owner
class CustomerReceipts(admin.ModelAdmin):
fields = ('abc', 'users')
list_display = ('abc', 'get_user')
form = CustomerReceiptsAdminForm
def save_model(self, request, obj, form, change):
obj.owner = form.cleaned_data['users']
obj.save()
def get_user(self, obj):
return User.objects.get(id=obj.owner).username
get_user.short_description = 'User'
This will handle all displaying in the admin view and selects the right customer upon editing.