Разрешить неверный аргумент ключевого слова в модели Django - PullRequest
0 голосов
/ 27 апреля 2018

Кто-нибудь знает, как запретить Django вызывать ошибку TypeError при сохранении, когда поле отсутствует? Я включил упрощенные модели ниже. По сути, я хотел бы передать атрибут name при создании тега. Затем пользовательское действие сохранения get_or_create TagDetail с именем и создает ассоциацию.

class TagDetail(models.Model):
    name = models.CharField(max_length=100, unique=True)

class Tag(models.Model):
    detail = models.ForeignKey(TagDetail, on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        abstract = True

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

В вашей модели тегов есть несколько полей, которые являются обязательными и не могут оставаться пустыми, content_type и object_id

ВЫ: Вы хотите передать атрибут name при создании тега. Затем пользовательское действие сохранения get_or_create TagDetail с именем и создает ассоциацию

Процесс состоит в том, что вы вызываете save () для Модели, затем вызываете get_or_create метод для создания TagDetails с именем ... Пока что проблем нет

Но когда вы сохраняете тег, даже с ассоциацией detail= tag_details_instance, вы фактически оставляете эти поля content_type и object_id пустыми. Вы не указали БД установить пустым или нулевым для этих полей

Решение № 1
Если у вас есть данные для этих полей, при создании тега обязательно присвойте им значения.

Решение № 2
Отредактируйте свою модель тега с помощью:

class Tag(models.Model):
    detail = models.ForeignKey(TagDetail, on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL,
        blank=True,null=True)
    object_id = models.PositiveIntegerField(blank=True,null=True)
    content_object = GenericForeignKey('content_type', 'object_id')

Если вам так важно сохранить то же поведение, что и on_delete = models.CASCADE в поле content_type, вы можете добавить сигнал pre/post_delete

0 голосов
/ 27 апреля 2018

Попробуйте переопределить метод save(), как показано ниже,

class TagDetail(models.Model):
    name = models.CharField(max_length=100, unique=True)


class Tag(models.Model):
    detail = models.ForeignKey(TagDetail, on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        tag_detail, created = TagDetail.objects.get_or_create(name=self.detail)
        self.detail = tag_detail
        super().save(*args, **kwargs)
0 голосов
/ 27 апреля 2018

Попробуйте установить blank=True для поля. Если вам это потребуется позже, вы можете указать это в форме.

...