TypeError at / cannot unpack non-iterable NoneType object (Django)
Я пытаюсь настроить систему в моем Django-проекте, где пользователи могут комментировать отдельные посты на главной (индексной) странице. Однако у меня возникает проблема, когда я пытаюсь сделать так, чтобы комментарий автоматически привязывался к посту.
Вот код, который я попробовал в файле views.py:
from django.core import paginator
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse
from .models import *
from django.views.generic import ListView, CreateView, UpdateView
from django.views.generic.detail import DetailView
from .forms import *
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.core.paginator import Paginator
from django.views import View
import random
def index(request, pk=None, *args, **kwargs):
postdata = Post_Data.objects.all()
profiledata = ProfileData.objects.all()
likedata = Like.objects.all()
dislikedata = Dislike.objects.all()
comment = PostComment.objects.all()
postid = Post_Data.objects.get(pk)
# Initialize the comment form
if request.method == 'POST':
comment_form = PostCommentForm(request.POST)
if comment_form.is_valid():
post = comment_form.save(commit=False)
post.user = request.user
post.save()
return redirect('/')
else:
comment_form = PostCommentForm() # Create an empty form
# Pass the comment form to the template context
return render(request, 'index.html', {
'title': 'RoamTrip',
'postdata': postdata,
'profiledata': profiledata,
'likedata': likedata,
'dislikedata': dislikedata,
'comment': comment,
'comment_form': comment_form # Make sure this is included
})
models.py:
from django.contrib import admin
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
from django.conf import settings
from .validators import validate_file_extension
# Create your models here.
class Post_Data (models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, # Set the appropriate behavior here
null=True
)
time_data = models.DateTimeField(help_text='Enter Time of Upload Here:', auto_now_add=True)
text_data = models.TextField(help_text='Type Here:')
image_data = models.ImageField(upload_to="website/media/", null=True, blank=True, help_text='Upload Image:')
video_data = models.FileField(null=True, upload_to="website/media/", blank=True, validators=[validate_file_extension])
public_data = models.BooleanField(help_text='Public?', null=True)
approval = models.BooleanField(help_text='Is this post approved?', default=True)
class PostComment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post_Data, on_delete=models.CASCADE, related_name='post_comment_id')
post_comment = models.CharField(max_length=500)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Comment by {self.user} on {self.post}"
urls.py:
urlpatterns = [
path('', views.index, name='RoamTrip'),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
В результате я получил эту ошибку:
TypeError: cannot unpack non-iterable NoneType object
Вот неисправная строка:
postid = Post_Data.objects.get(pk)
.get()
принимает аргументы в виде ключевых слов или объектов Q. Я предполагаю, что вы хотите фильтровать по PK, поэтому строка должна быть такой:
postid = Post_Data.objects.get(pk=pk)
def index(request, pk=None, *args, **kwargs):
postdata = Post_Data.objects.all()
profiledata = ProfileData.objects.all()
likedata = Like.objects.all()
dislikedata = Dislike.objects.all()
comment = PostComment.objects.all()
if pk:
post = get_object_or_404(Post_Data, pk=pk)
else:
post = None
if request.method == 'POST':
comment_form = PostCommentForm(request.POST)
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.user = request.user
if post:
comment.post = post
comment.save()
return redirect('/')
else:
comment_form = PostCommentForm()
return render(request, 'index.html', {
'title': 'RoamTrip',
'postdata': postdata,
'profiledata': profiledata,
'likedata': likedata,
'dislikedata': dislikedata,
'comment': comment,
'comment_form': comment_form,
'target_post': post
})
Можете ли вы попробовать это? Жду ваших отзывов
Я думаю, что есть много проблем.
В соответствии с ответом @Michal, эту часть следует переделать следующим образом.
postid = Post_Data.objects.get(pk=pk)
urls.py также имеет проблему.
В настоящее время функция index имеет параметр pk. Если вы посмотрите на эту часть, ожидается, что вы попытаетесь использовать динамический url для этой логики.
def index(request, pk=None, *args, **kwargs):
...
Поэтому путь, вызывающий функцию index, должен быть в виде динамического url.
urlpatterns = [
path('yourURL/<int:pk>/', views.index, name='RoamTrip'),
]
...
Поскольку в вашем коде не используются динамические url, я ожидаю, что при выполнении функции index функция pk будет равна None, что приведет к ошибке DoesNotExists.
def index(request, pk=None, *args, **kwargs):
...
postid = Post_Data.objects.get(pk=pk) # pk=None --> DoesNotExists
А в приведенном вами коде post_id не используется в функции index.