我最近开始评估Django迁移我们10年前编写的古老Web应用程序。我最近几天一直在阅读Django文档,但是在我的案例中找不到实现多表数据库连接的最佳方法:
Model:
class Product(models.Model):
productid = models.IntegerField(primary_key=True, db_column='ProductId')
productname = models.CharField(max_length=120, db_column='ProductName')
class Testcases(models.Model):
testcaseid = models.IntegerField(primary_key=True, db_column='TestCaseId')
testcasename = models.CharField(max_length=240, db_column='TestCaseName')
class Testmatrix(models.Model):
testmatrixid = models.IntegerField(primary_key=True, db_column='TestMatrixId')
productid = models.ForeignKey(Product, db_column='ProductId')
testcaseid = models.ForeignKey(Testcases, db_column='TestCaseId')
class Status(models.Model):
testmatrixid = models.ForeignKey(Testmatrix, db_column='TestMatrixId')
title = models.CharField(max_length=240, db_column='Title', blank=True)
(注意,模型是由inspectdb生成的,我不想在此时修改它)
View:
from django.shortcuts import render_to_response
from mysite.testmatrix.models import Product, Testcases, Testmatrix, Status
def get_products(request):
tm = list(Testmatrix.objects.filter(productid='abc'))
return render_to_response('products.html', {'tm': tm})
模板目前设计为最小,以帮助关注(视图/模型)中的实际问题。
Template: (products.html)
{% extends "main.html" %}
{% block body %}
<table>
{% for tm in tm %}
<tr>
<td>{{ tm.testmatrixid }}</td>
<td>{{ tm.testcaseid.testcasename }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
问题:
虽然我能够加入Testmatrix和Testcase模型,但我无法通过加入所有TestMatrix,TestCase,状态记录来生成等效的查询集,比如说productid ='abc'
我尝试了以下内容:
1)在Testmatrix和Testcases与Product表之间使用select_related,并且能够访问所有三个模型的属性(testmatrixid,productid,productname,testcaseid,testcasename)。但是,我不确定如何扩展此自动外键引用状态模型。如果在Testmatrix本身中定义了所有外键,这将更容易。但是Status有一个TestMatrix的外键。
2)我尝试使用类似:entries = Status.objects.filter(testmatrixid__productid = pid)。这再次给了我一个查询集,作为加入Testmatrix和Status的结果,而不是Testcases。
原谅任何明显的错误或蠢货。这是我的第一篇文章!
答案 0 :(得分:2)
因此您需要访问related_object。这很简单。
首先,在此处添加related_name
:
class Status(models.Model):
testmatrixid = models.ForeignKey(Testmatrix, db_column='TestMatrixId', related_name='statuses')
现在您可以获得所需的Testmatrix的所有状态,如
test_matrix.statuses.all()
如果您不想点击数据库,当您访问statuses
时,请不要忘记使用select_related
。
答案 1 :(得分:0)
如果没有任何特定的错误消息,很难诊断出错误的原因。但是,在您的示例中,在views.get_products中:tm = list(Testmatrix.objects.filter(productid='abc'))
将不起作用,因为'abc'是一个字符串,您的productid实际上是一个Product对象(不只是一个整数,即使该字段是整数外键到参考表的pk);你可以做tm = list(Testmatrix.objects.filter(productid=Product.objects.get(product_name='abc'))
,假设'abc'是产品记录的产品名称。当您将字段设置为models.ForeignKey(...)时,您将该引用记录作为对象而不是id。
除此之外,没有什么明显的,你的模板看起来很稳固,你的模型看起来很好。我建议创建一些测试用例以查看错误所在:Django Testing;此外,this也是了解使用Django进行TDD和单元测试的好教程。使用单元测试,您可以验证应用程序的每个步骤,并在保证的情况下进行将来的更新。