使用具有多对多模型的Django管理面板对象创建功能

时间:2018-05-28 13:42:22

标签: django django-models django-admin

我正在尝试使用django管理板功能,以便能够将管理面板中的数据插入到具有一对多和多对多关系的表中。我使用了__str__功能(Python 3.6),以便在管理面板中创建可理解的字符串,而不是像"Testcase object(1)"那样描述,以便能够为executiontests模型选择正确的testcase id和testrun id。但它看起来像在执行测试对象创建期间的管理面板而不是测试用例id值和testrun id值尝试将外部int键设置为相应的文本值。 我悲惨地失败了:

tc = Testcases.objects.get(pk=self.testcase_id)
...
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Testcases'

型号:

class Testcases(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return f"Testcase: {self.name}"


class Testruns(models.Model):
    starttime = models.TimeField()
    endtime = models.TimeField()

    def __str__(self):
        return f"Testrun: {self.starttime} - {self.endtime}"


class Executedtests(models.Model):
    testcase_id = models.ForeignKey("testcases", models.CASCADE)
    testrun_id = models.ForeignKey("testruns", models.CASCADE)
    teststart = models.TimeField(blank=True, null=True)  # This field type is a guess.
    testend = models.TimeField(blank=True, null=True)  # This field type is a guess.

    def __str__(self):
        tc = Testcases.objects.get(pk=self.testcase_id)
        tr = Testruns.objects.get(pk=self.testrun_id)
        return f"{tc}(tr), Start: {self.teststart}, End: {self.testend}"

内部应用admin.py我只是注册了所有这些模型。

管理表单的select标签看起来不错:

<select id="id_testcase_id" name="testcase_id">
    <option value="1">Testcase: Test1</option>
    ...
</select>

1 个答案:

答案 0 :(得分:3)

如果您定义fieldnameForeignKey,Django会自动添加一个包含该对象主键的额外字段fieldname_id。所以这里Django构造了一个testcase_id_id,它包含它所引用的Testcases实例的主键,但这使得它在语义上相当“丑陋”。

因此,在它引用的项之后命名关系更加一致,并让Django生成fieldname_id,这样您仍然可以提取(并查询)该值。

因此,最小的修复是:

class Executedtests(models.Model):
    # rename the relations (drop the _id suffix)
    testcase = models.ForeignKey("testcases", models.CASCADE)
    testrun = models.ForeignKey("testruns", models.CASCADE)
    teststart = models.TimeField(blank=True, null=True)  # This field type is a guess.
    testend = models.TimeField(blank=True, null=True)  # This field type is a guess.

    def __str__(self):
        tc = Testcases.objects.get(pk=self.testcase_id)
        tr = Testruns.objects.get(pk=self.testrun_id)
        return f"{tc}(tr), Start: {self.teststart}, End: {self.testend}"

您的视图将起作用,因为testcase_id将不再包含Testcases实例(外键采用您引用的模型的类型),而是主键。

通过调用someexecutedtests.testcase,您可以 获取testcase的主键,但Testcases实例本身(如果尚未获取) ,Django通常会执行另一个查询)。