Whenever I run my code, I get a "RelatedManager" object is not iterable error. Here is my models.py:
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.urls import reverse
class Post(models.Model):
contents = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
replies = list()
def __str__(self):
return f'{self.author} - {self.pk} - {self.date_posted}'
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Reply(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='replies')
contents = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return f'{self.author} - {self.date_posted}'
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Meta:
ordering = ['-date_posted']
Here is my views.py:
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from .forms import ReplyForm
class PostListView(ListView):
model = Post
template_name = 'app/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 15
def PostDetailView(request, **kwargs):
template_name = 'app/post_detail.html'
post = get_object_or_404(Post, pk=kwargs['pk'])
replies = post.replies
new_reply = None
# Reply added
if request.method == 'POST':
reply_form = ReplyForm(data=request.POST)
if reply_form.is_valid():
# Create reply object but don't save to db yet
new_reply = reply_form.save(commit=False)
# Assign the current post the the reply
new_reply.post = post
# Save reply to db
new_reply.save()
replies.append(new_reply)
else:
reply_form = ReplyForm()
return render(request, template_name, {'post':post, 'replies':replies, 'form':reply_form})
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['contents']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields = ['contents']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
else:
return False
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post
success_url = '/'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
else:
return False
def about(request):
return render(request, 'app/about.html', {'title':'About App'})
def n_help(request):
return render(request, 'app/help.html', {'title':'App Help Page'})
The problem is when I try to iterate through the Post.replies list, it gives me a Related Manager instead of the list I intended it to be. Here is the variables in the Django debug page:
kwargs: {'pk':8}
new_reply: None
post: <Post: TestUser - 8 - 2022-02-06 00:12:33.255956+00:00>
replies: <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x00000262D26052E0>
reply_form: <ReplyForm bound=False, valid=False, fields=(contents)>
request: <WSGIRequest: GET '/post/8/'>
template_name: app/post_detail.html
As you can see the "replies" variable is a related manager, not a list. I tried making replies
global and using a function to return it as a list, which worked but it still gave me the RelatedManager
error. The only difference was the Django Debug variables looked like this:
kwargs: {'pk':8}
new_reply: None
post: <Post: TestUser - 8 - 2022-02-06 00:12:33.255956+00:00>
replies: []
reply_form: <ReplyForm bound=False, valid=False, fields=(contents)>
request: <WSGIRequest: GET '/post/8/'>
template_name: app/post_detail.html
Even though replies
is now a list and that is the only thing I am iterating through, it still gives me the exact same error. I would appreciate any help given.