TypeError: ‘NoneType’ object is not iterable

when testing a site using pytest, I get an error in the test, and I can’t figure out what is causing the error, please tell me where exactly the problem is in my code, and how to fix it (Files with tests cannot be changed - pytest). My code views.py:

from django.views.generic import (
    CreateView, DeleteView, DetailView, ListView, UpdateView
)
from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.contrib.auth.forms import PasswordChangeForm
from django.urls import reverse_lazy
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.mixins import UserPassesTestMixin

from blog.models import Category, Post
from .models import Comment
from .forms import CommentForm
from .forms import PostForm
from .forms import UserProfileForm


User = get_user_model()


class OnlyAuthorMixin(UserPassesTestMixin):

    def test_func(self):
        object = self.get_object()
        return object.author == self.request.user


class PostListView(ListView):
    model = Post
    queryset = (
        Post.published
        .order_by('-pub_date')
    )
    paginate_by = 10
    template_name = 'blog/index.html'


class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    form_class = PostForm
    template_name = 'blog/create.html'

    def get_success_url(self):
        return reverse_lazy(
            'blog:profile',
            kwargs={'username': self.request.user.username}
        )

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)


class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/detail.html'
    context_object_name = 'post'

    def get_object(self, queryset=None):
        post_id = self.kwargs.get("post_id")
        return get_object_or_404(Post, pk=post_id)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if context is None:
            context = {}
        context['form'] = CommentForm()
        if self.object:
            context['comments'] = self.object.comments.select_related('author')
            context['comments_count'] = self.object.comments.count()
        else:
            context['comments'] = []
            context['comments_count'] = 0
        return context


@login_required
def add_comment(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    form = CommentForm(request.POST)
    if form.is_valid():
        print("Form is valid")
        comment = form.save(commit=False)
        comment.author = request.user
        comment.post = post
        comment.save()
        return redirect('blog:post_detail', post_id=post_id)
    return render(request, 'blog/detail.html', {
        'form': form,
        'post': post,
        'comments': post.comments.select_related('author'),
        'comments_count': post.comments.count()
    })


@login_required
def edit_comment(request, post_id, comment_id):
    comment = get_object_or_404(Comment, id=comment_id)
    if comment.author != request.user:
        return redirect('blog:post_detail', post_id=post_id)
    if request.method == 'POST':
        form = CommentForm(request.POST, instance=comment)
        if form.is_valid():
            form.save()
            return redirect('blog:post_detail', post_id=post_id)
    else:
        form = CommentForm(instance=comment)
    return render(
        request, 'blog/comment.html',
        {'form': form, 'comment': comment}
    )


@login_required
def delete_comment(request, post_id, comment_id):
    comment = get_object_or_404(Comment, id=comment_id)
    if comment.author != request.user and not request.user.is_superuser:
        return redirect('blog:post_detail', post_id=post_id)
    if request.method == 'POST':
        comment.delete()
        return redirect('blog:post_detail', post_id=post_id)
    return render(request, 'blog/comment.html', {'comment': comment})


@login_required
def edit_profile(request):
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
            return redirect('blog:profile', username=request.user.username)
    else:
        form = UserProfileForm(instance=request.user)
    return render(request, 'blog/edit_profile.html', {'form': form})


@login_required
def change_password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            update_session_auth_hash(request, user)
            return redirect('blog:profile', username=request.user.username)
    else:
        form = PasswordChangeForm(request.user)
    return render(request, 'blog/password_change_done.html', {'form': form})


class PostUpdateView(LoginRequiredMixin, OnlyAuthorMixin, UpdateView):
    model = Post
    form_class = PostForm
    template_name = 'blog/create.html'

    def get_success_url(self):
        return reverse_lazy(
            'blog:post_detail',
            kwargs={'post_id': self.object.pk}
        )

    def get_object(self, queryset=None):
        post_id = self.kwargs.get('post_id')
        return get_object_or_404(Post, pk=post_id)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if context is None:
            context = {}
        return context

    def dispatch(self, request, *args, **kwargs):
        return redirect('blog:post_detail', post_id=self.kwargs.get('post_id'))


class PostDeleteView(LoginRequiredMixin, OnlyAuthorMixin, DeleteView):
    model = Post
    template_name = 'blog/create.html'
    success_url = reverse_lazy('blog:index')

    def get_object(self, queryset=None):
        post_id = self.kwargs.get('post_id')
        return get_object_or_404(Post, pk=post_id)
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if context is None:
            context = {}
        return context


class CategoryPostsView(ListView):
    model = Category
    template_name = 'blog/category.html'
    context_object_name = 'page_obj'
    paginate_by = 10

    def get_queryset(self):
        category_slug = self.kwargs.get('category_slug')
        category = get_object_or_404(
            Category,
            slug=category_slug,
            is_published=True
        )
        return category.posts(manager='published').order_by('-pub_date')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if context is None:
            context = {}
        category_slug = self.kwargs.get('category_slug')
        category = get_object_or_404(
            Category,
            slug=category_slug,
            is_published=True
        )
        context['category'] = category
        return context


class ProfileView(DetailView):
    model = User
    template_name = 'blog/profile.html'
    context_object_name = 'profile'

    def get_object(self):
        username = self.kwargs.get("username")
        return get_object_or_404(User, username=username)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if context is None:
            context = {}
        user = self.get_object()
        posts = Post.objects.filter(author=user).order_by('-pub_date')
        paginator = Paginator(posts, 10)
        page_number = self.request.GET.get('page')
        page_obj = paginator.get_page(page_number)
        context['page_obj'] = page_obj
        return context

Error when running pytest:

============================================================================ FAILURES ============================================================================ ___________________________________________________________________________ test_post ____________________________________________________________________________

published_category = <Category: Break Star Clear Responsibility Once Rest>, published_location = <Location: Bianca Roach DVM>
user_client = <django.test.client.Client object at 0x000002DF6F6B7E60>, another_user_client = <django.test.client.Client object at 0x000002DF6F798980>
unlogged_client = <django.test.client.Client object at 0x000002DF6F79A690>
comment_to_a_post = <Comment: Comment by deannawillis on Serve Moment Small Those Note Difficult>
create_post_context_form_item = KeyVal(key='form', val=<PostForm bound=False, valid=False, fields=(title;text;pub_date;location;category;image)>)
PostModel = <class 'blog.models.Post'>, CommentModelAdapter = <class 'adapters.comment.CommentModelAdapter.<locals>._CommentModelAdapter'>
main_content_tester = <test_content.MainPostContentTester object at 0x000002DF6F7A0CE0>

    @pytest.mark.django_db(transaction=True)
    def test_post(
            published_category: Model,
            published_location: Model,
            user_client: django.test.Client,
            another_user_client: django.test.Client,
            unlogged_client: django.test.Client,
            comment_to_a_post: Model,
            create_post_context_form_item: Tuple[str, BaseForm],
            PostModel: Type[Model],
            CommentModelAdapter: CommentModelAdapterT,
            main_content_tester: MainPostContentTester
    ):
        _, ctx_form = create_post_context_form_item

        create_a_post_get_response = get_create_a_post_get_response_safely(
            user_client
        )

        response_on_created, created_items = _test_create_items(
            PostModel,
            PostModelAdapter,
            another_user_client,
            create_a_post_get_response,
            ctx_form,
            published_category,
            published_location,
            unlogged_client,
            user_client,
        )

        # checking images are visible on post creation
        created_content = response_on_created.content.decode('utf-8')
        img_count = created_content.count('<img')
        expected_img_count = main_content_tester.n_or_page_size(len(created_items))
        assert img_count >= expected_img_count, (
            'Убедитесь, что при создании публикации она отображается с картинкой.'
        )

>       edit_response, edit_url, del_url = _test_edit_post(
            CommentModelAdapter,
            another_user_client,
            comment_to_a_post,
            unlogged_client=unlogged_client,
            user_client=user_client,
        )

tests\test_post.py:111:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  
tests\test_post.py:360: in _test_edit_post
    edit_response = _test_edit(
tests\test_edit.py:46: in _test_edit
    updated_form = create_updated_form(**update_props)
tests\test_edit.py:35: in create_updated_form
    _, form = _testget_context_item_by_class(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  

context = None, cls = <class 'django.forms.forms.BaseForm'>, err_msg = '', inside_iter = False

    def _testget_context_item_by_class(
            context, cls: type, err_msg: str, inside_iter: bool = False
    ) -> KeyVal:
        """If `err_msg` is not empty, empty return value will
        produce an AssertionError with the `err_msg` error message"""

        def is_a_match(val: Any):
            if inside_iter:
                try:
                    return isinstance(iter(val).__next__(), cls)
                except Exception:
                    return False
            else:
                return isinstance(val, cls)

        matched_keyval: KeyVal = KeyVal(key=None, val=None)
        matched_keyvals: List[KeyVal] = []
>       for key, val in dict(context).items():
E       TypeError: 'NoneType' object is not iterable

tests\conftest.py:302: TypeError

I tried to check the value of context for None, if context gets the value None, assigned an empty dictionary in the PostDetailView, PostUpdateVew, ProfileView classes, but as a result I also get an error when running pytest

Back to Top