Ошибка значения. Не удается назначить набор запросов. Это должен быть экземпляр

#python #django #django-queryset #valueerror

#python #django #django-queryset #ошибка значения

Вопрос:

Я хочу создать объект в моей модели комментариев. Это моя модель ответа на сообщение.

 class Reply(MPTTModel):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

    detail = models.CharField(max_length=50, null=True, blank=True, unique=True)

    pub_date = models.DateTimeField(auto_now_add=True)
    last_edited = models.DateTimeField(auto_now=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    class MPTTMeta:
        order_insertion_by = ['name']
 

Это моя функция просмотра для ответа.

 def post_detail(request,id,**kwargs):
    post = Post.objects.all().filter(id=id)
    comment = CommentReply.objects.filter(post=id)
    context = {'post': post, 'comment': comment}
    if request.method == 'POST':
        comments = request.POST.get('comment')
        Reply.objects.create(
                post=post, detail=comments, author = request.user)
    else:
        return render(request, 'khalidblog_app/full_detail.html', context)

    return render(request,'khalidblog_app/full_detail.html',context)
 

Я использую цикл for в своем шаблоне:

 {% for post in post %}
    <img alt='' src='{{ post.image.url }}' class='avatar avatar-80 photo' height='80' width='80' />
    <div class="eltd-author-description-text-holder">
        <h5 class="eltd-author-name"> {{post.author}} </h5>
    <div class="eltd-author-text">
        <p>{{post.title}}</p>
    </div>
    <div class="eltd-author-text">
        <p>{{post.content}}</p>
        <hr>
    </div>
{%endfor%}
 

Когда я запускаю эту функцию просмотра, она показывает ошибку значения следующим образом.

 Cannot assign "<QuerySet [<Post: Author : zorainTiTleFirst PostDated :2021-01-17 16:27:47.043869 00:00>]>": "Reply.post" must be a "Post" instance.
 

Как я могу установить forignkey (Post) в этой модели ответа, используя эту функцию просмотра?

Комментарии:

1. измените эту строку: post = Post.objects.all().filter(id=id) на post = Post.objects.filter(id = id).first() Он вернет первый объект в фильтре. Если вы используете get следующим образом: post = Post.objects.get(id=id), это вызовет исключение, если объект не существует. Вы также можете сделать: post = Post.objects.filter(id = id)[0]

Ответ №1:

В самой первой строке вашей функции вы используете метод .filter(), который возвращает набор запросов (короче говоря, список объектов), где в идеале вы должны были использовать метод .get() . .get() возвращает один объект, который фактически ожидает присвоение в строке 6.

Комментарии:

1. когда я попробовал .get, тогда он говорит, что объект post не может быть повторен. Итак, это означает, что я должен использовать другую переменную для создания объекта. следующим образом … post1 =Post.objects.get(id= id) Reply.objects.create(post=post1, detail=comments, author = request.user)

Ответ №2:

Ваша переменная ‘post’ указывает на набор запросов объектов Post, а не на один экземпляр. Вы должны использовать get() вместо filter() следующим образом:

 post = Post.objects.get(id=id)
 

Обновление: вы поделились в комментариях, что использовали цикл for в своем шаблоне. Цикл for предназначен для перебора группы объектов (например, набора запросов, который будет возвращен с помощью filter()). Если вы просто хотите отобразить значения полей для одного экземпляра, вам не нужно использовать цикл for .

Вот ссылка на документы Django для filter(), которая возвращает набор запросов (группу объектов).

Вот ссылка на документы Django для get() — который возвращает один объект.

Комментарии:

1. Однако это не связано с вашим вопросом, в представлении нет необходимости в вашем else:. Обратный вызов в этом операторе else является повторением приведенного ниже обратного вызова, который все равно будет выполнен.

2. когда я попробовал .get, тогда он говорит, что объект post не может быть повторен. Итак, это означает, что я должен использовать другую переменную для создания объекта. следующим образом … post1 =Post.objects.get(id= id) Reply.objects.create(post=post1, detail=comments, author = request.user)

3. Похоже, что эта вторая ошибка, на которую вы ссылаетесь, может быть связана с кодом в вашем HTML-шаблоне. Пожалуйста, не могли бы вы также поделиться этим? Возможно, вы используете forloop, например, для чего-то в post, что не имело бы смысла.

4. Да, я использую цикл for . {% для сообщения в сообщении %} <img alt=» src=»{{ post.image.url }}» class=’аватар аватар-80 фото’ height=’80’ width=’80’ /> <div class=»eltd-author-description-text-держатель»> <h5 class=»eltd-author-name»> {{post.author}} </h5> <div class=»eltd-author-text»> <p>{{post.title}}</p></div> <div class=»eltd-author-text»> <p>{{post.content}}</p> <hr> </div> {%endfor%}

5. Если я не использую for, тогда сообщение не отображается.

Ответ №3:

поскольку ваша переменная ‘post’ указывает на набор запросов объектов Post, вы можете напрямую выбрать первый элемент в наборе запросов следующим образом :

  Reply.objects.create(
                post=post[0], detail=comments, author = request.user)
 

Комментарии:

1. это решение уже упоминалось в комментариях

2. Да, сэр, я понял.