Использование функциональности создания объектов панели администратора Django с несколькими моделями - PullRequest
0 голосов
/ 28 мая 2018

Я пытаюсь использовать функции админ-панели django, чтобы иметь возможность вставлять данные из админ-панели в таблицы с отношениями «один ко многим» и «несколько ко многим».Я использовал функциональность __str__ (Python 3.6) для создания понятных строк в административной панели вместо "Testcase object(1)" подобного описания, чтобы иметь возможность выбрать правильный идентификатор тестового случая и идентификатор тестового запуска для модели executetests.Но похоже, что панель администратора при создании объекта executetest вместо значения идентификатора testcase и значения идентификатора testrun пытается установить для внешних ключей 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 id="id_testcase_id" name="testcase_id">
    <option value="1">Testcase: Test1</option>
    ...
</select>

1 Ответ

0 голосов
/ 28 мая 2018

Если вы определяете fieldname, то есть ForeignKey, Django автоматически добавляет дополнительное поле fieldname_id, которое содержит первичный ключ этого объекта.Итак, здесь Django построил testcase_id_id, который содержит первичный ключ экземпляра Testcases, на который он ссылается, но это делает его семантически довольно " некрасивым ".

более логично называть отношение после элемента, на который оно ссылается, и позволить Django сгенерировать fieldname_id, так что вы все равно сможете извлечь (и запросить) это значение.

Таким образом, минимальное исправление:

class Executedtests(models.Model):
    # rename the relations (drop the _id suffix)
    <b>testcase</b> = models.ForeignKey("testcases", models.CASCADE)
    <b>testrun</b> = 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 обычно выполняет другой запрос).

...