ReverseManyToOne создать объект от детей через форму Django - PullRequest
0 голосов
/ 17 октября 2019

Использование:

Python 3.7.3

django 2.2.5

mysql 5.7.27

У меня есть следующие модели:

class Item(models.Model):
...

class Comments(models.Model):
    Item = models.ForeignKey('Item', default=None, null=True, on_delete=models.CASCADE)
    Comment = models.TextField(max_length=512, default="", blank=True)

Я хотел бы создать объект Comments при создании Item через форму django. Я пытался сделать:

class ItemInsertForm(forms.ModelForm):
...

    Comments = forms.CharField(required=False,
                              widget=forms.Textarea(attrs={'placeholder':"Use comments to describe item details \
                                                                         or issues that other users should know",
                                                           'rows':5,
                                                           'cols':50,
                                                           }
                                                    )
                              )

    def clean_Comments(self, *args, **kwargs):
        _comment = self.cleaned_data.get('Comments')
        _comments = Item.comments_set.create(Comment=_comment)
        return _comments

, но я получаю следующую ошибку:

У объекта 'ReverseManyToOneDescriptor' нет атрибута 'create'

ОбаТаблицы пусты, поэтому в настоящее время не существует элементов и комментариев. Я думаю, именно поэтому нет доступного метода создания. Есть ли способ, которым я мог бы достичь того, чего я хочу?

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

1 Ответ

0 голосов
/ 17 октября 2019

Я вижу довольно много проблем с вашим кодом, но, поскольку я чувствую, что вы сделали это честно, я постараюсь помочь вам как можно лучше.

Прежде всего ваши модели. py файл:

  • Имена моделей должны быть единичными, поэтому вместо Comments используйте Comment.
  • Члены класса должны быть в нижнем регистре, поэтому Item и Commentследует изменить на item и comment.
  • Comment.comment все еще не очень наглядно. Комментарий - это фактический объект, его содержимое - текст внутри комментария, поэтому здесь уместнее будет text.
  • ForeignKey с null=True уже устанавливает по умолчанию значение None.

Принимая это во внимание и очищая свои модели. Py:

class Item(models.Model):
...

class Comment(models.Model):
    item = models.ForeignKey(Item, null=True, on_delete=models.CASCADE)
    text = models.TextField(max_length=512, default="", blank=True)

Затем перейдем к вашей форме:

  • Поскольку это форма для созданияComments, более подходящее имя будет CommentForm.
  • def clean_Comments(self, *args, **kwargs): - это функция, зарезервированная для проверки в поле Comments, а не для создания объекта из ввода формы. Для этого вы можете использовать метод ModelForm save(). Вам нужно только определить метод сохранения, если вы собираетесь выполнить какую-то собственную логику.

Давайте сначала исправим эти проблемы, прежде чем перейти к сообщению об ошибке, которое вы получаете:

class ItemInsertForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['text']

    text = forms.CharField(required=False,
                              widget=forms.Textarea(attrs={'placeholder':"Write your comment to describe item details \
                                                                         or issues that other users should know",
                                                           'rows':5,
                                                           'cols':50,
                                                           }
                                                    )
                              )

Эта форма при отправке создаст объект Comment. Однако по-прежнему нет возможности добавить комментарий к Item.


Для этого необходимо убедиться, что в базе данных есть Item экземпляров, или разрешить пользователю создать один из них с помощью ItemForm. Есть несколько способов сделать это:

  1. Добавьте ModelChoiceField в CommentForm, что позволит пользователю выбирать элемент из выбора.
  item = forms.ModelChoiceField(queryset=Item.object.all(),
                                  to_field_name = '<item_name>',
                                  empty_label="Select an Item")
Когда вы хотите добавить эту форму к чему-то вроде ItemDetailPage, вы можете использовать текущий элемент, используя что-то вроде
  item = Item.objects.get(pk=<item_id>)

или

  item = Item.objects.create(<item_properties_here>)

затем, при сохранении формы:

  comment = form.save()
  comment.item = item.
  comment.save()

Третий способ - это то, что вы пытались и почему вы получили ошибку. Получите элемент, затем добавьте комментарий, сохраненный из формы, в item.comment_set.

Примерно так:

  item = Item.objects.get(pk=<item_id>)
  comment = form.save()
  item.comments_set.add(comment)
  item.save()
...