Передача полей модели в функции в качестве параметров для создания других полей django - PullRequest
0 голосов
/ 12 июля 2019

Я продолжаю свой вопрос Создание новых объектов с определенными параметрами . Я пытался выяснить, как написать функции в моих моделях Django для создания значений по умолчанию на полях. Я знаю, как это сделать, но теперь хотел бы сделать еще один шаг, добавив параметры в функции и используя предыдущие поля в качестве параметров. До сих пор я пробовал следующее, и каждый из них выдавал свои собственные сообщения об ошибках при попытке их перенести.

class NewTest(models.Model):
    score = models.IntegerField(default=0)
    def num(score): # Want the score parameter to be the score field
        new_num = score
        return new_num
    last_score = models.IntegerField(default=num(score))
Error: int() argument must be a string, a bytes-like object or a number, not 'IntegerField'


class NewTest(models.Model):
    score = models.IntegerField(default=0)
    def num(self):
        new_num = self.score
        return new_num
    last_score = models.IntegerField(default=num(self))
NameError: name 'self' is not defined


class NewTest(models.Model):
    score = models.IntegerField(default=0)
    def num():
        new_num = self.score
        return new_num
    last_score = models.IntegerField(default=num)
NameError: name 'self' is not defined

Кто-нибудь знает, как это сделать, или знает, где есть документация по этому вопросу?

1 Ответ

0 голосов
/ 12 июля 2019

Поле модели Django default callable на самом деле не может быть методом экземпляра. Из-за того, как этот вызываемый объект используется в миграциях, он должен быть сериализуемым для миграций, например, в миграциях вы увидите ссылку на путь к функции, например default="my_app.models.my_callable_default".

То, как я видел другие решения, - это переопределить метод моделей save, чтобы проверить эти поля и установить там значение по умолчанию.

class NewTest(models.Model):
    score = models.IntegerField(default=0)
    last_score = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        if not self.pk:  # Check for create
            self.last_score = self.score
        else:
            # Get the existing score from the database, because this instance has been modified
            score_from_db = NewTest.objects.values("score").get(pk=self.pk)["score"]
            self.last_score = self.score
        return super().save(*args, **kwargs)  # Continue with save as normal

Это решение переопределяет метод save вашей модели, чтобы назначить другое значение поля для поля last_score во время создания, и если это обновление, оно извлечет существующий объект из базы данных, чтобы получить последний результат (I ' Я не уверен, что это то, что вам нужно). if not self.pk используется для проверки, вызывается ли текущее сохранение для нового объекта (создание) или существующего объекта (обновление), потому что база данных назначает первичный ключ во время создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...