我正在为我们的django应用程序编写测试。 遗憾的是,我们不得不使用多个数据库布局,无法改变这种情况。 (跨多个数据中心的不同服务器上具有多个后端的分布式数据库)
我们有两个数据库:
对于这些模型,我们编写了django网站上记录的不同路由器。 现在问题是,如果我运行python manage.py测试customerreceipts测试框架在几秒钟后死亡,并出现以下错误:
django.db.utils.ProgrammingError: relation "auth_user" does not exist
我检查了创建的数据库,但没有表格。因此,来自模型的查询会引发错误。
问题模型是(在数据库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())
由于多个数据库设置不支持直接链接,因此我们为所有者使用IntegerField,业务逻辑处理完整性。
问题是_choices_user()为缺少的表设置查询。我不明白为什么django在第一次运行时没有创建表auth_user。如果我使用导致模型删除应用程序,则测试框架正常运行。
任何想法如何解决?
谢谢!
编辑: 我创建了一个数据库设置并尝试了同样的事情。可悲的是它抛出同样的错误! 我现在很困惑。有人也可以测试一下吗?使用_choices_user方法创建模型并运行test。
答案 0 :(得分:1)
您可以手动选择数据库。只需使用()调用即可。方法 using()只接受一个参数:要运行查询的数据库的别名。
def _choices_user():
users = User.objects.using('default').all()
.....
.....
答案 1 :(得分:0)
这不是一个完美的答案,而是目前唯一的方法:
模型(删除的选项):
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")
管理:
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'
这将处理管理视图中的所有显示,并在编辑时选择合适的客户。