for loop is not checking all the names

I am building a Book Blog App and I am trying to get cleaned_data in creation form and I am implementing a feature in which "User can add multiple books (like tags) in blogpost which are saved in another model" And If any of book name (Book Tag) mentioned in the form not in the Book List than It will show error "You cannot create a new book name"

So I made an if else statement to check if typed book name is in existing book in Book Model BUT Than it worked perfectly BUT The Problem occurred When someone types 3 book names and one of them book name is in saved book name than , it will not see other book names which are not saved (It is saving the post), So it will not show error

So I think I would access all the mentioned book names mentioned in form by .all() method ( So it will check if any of book name is not in the existing names) but this error is keep showing.

‘list’ object has no attribute ‘all’

models.py

class BlogPost(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=30, default='')
    body = models.CharField(max_length=30, default='')
    book_names = models.CharField(max_length=30,default='')

class Book(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    existing_book_names = models.CharField(max_length=30,default='')

views.py

def new_blog_post(request):
    ExistingNames = Book.objects.all().values_list('name', flat=True)

    if request.method == 'POST':
        form = BlogForm(request.POST, request.FILES)
        if form.is_valid():
            names = form.cleaned_data['book_names']
            new_post = form.save(commit=False)
            new_post.post_owner = request.user

            for inputTags in names.all():
                if inputTags in ExistingNames:
                    form.save()
                    return redirect('blogs')
                else:
                    messages.error(
                        request, 'You cannot add new name.')

    else:
        form = BlogForm()

    context = {'form': form}
    return render(request, 'new_blog_post.html', context)

I have tried many times but it didn’t worked.

I will really appreciated your Help. Thank You

Answer

You have the usual mistake of having a loop to check if everything fulfils some requirement, but acting immediately when encountering the first element which meets the requirement.

So

for inputTag in names: # removed the all(), inputTag is a single one at a time
  if inputTag in ExistingNames:
    form.save()
    return redirect('blogs')
  else:
    messages.error(
      request, 'You cannot add new name.')

should act after the loop instead, storing the success/fail in a variable:

everythingisfine = True              # the new variable

for inputTag in names:               # removed the all()
  if inputTag not in ExistingNames:
    everythingisfine = False
    break                            # if one failed, no need to check the rest

if everythingisfine:                 # checking the new variable, after the loop
  form.save()
  return redirect('blogs')
else:
  messages.error(
    request, 'You cannot add new name.')

but, you are right about all() being a thing, it can make the construct much shorter:

everythingisfine = all(inputTag in ExistingNames for inputTag in names)

if everythingisfine:                 # checking the new variable, after the loop
  form.save()
  return redirect('blogs')
else:
  messages.error(
    request, 'You cannot add new name.')