#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. Да, сэр, я понял.