django FieldError: Cannot resolve keyword 'category_name_contains' into field. Choices are: category, description, id, image, name, order, price

Viewed 206

I want to build a food delivering app, but facing this error. "FieldError: Cannot resolve keyword 'category_name_contains' into field. Choices are: catego ry, description, id, image, name, order, price".

This is the query.py:

try:
                model = field.model._meta.concrete_model
            except AttributeError:
                # QuerySet.annotate() may introduce fields that aren't
                # attached to a model.
                model = None
        else:
            # We didn't find the current field, so move position back
            # one step.
            pos -= 1
            if pos == -1 or fail_on_missing:
                available = sorted(
                    [
                        *get_field_names_from_opts(opts),
                        *self.annotation_select,
                        *self._filtered_relations,
                    ]
                )
                raise FieldError(
                    "Cannot resolve keyword '%s' into field. "
                    "Choices are: %s" % (name, ", ".join(available))
                )
            break

This is the views.py

from ast import Return
from multiprocessing import context
from django.shortcuts import render
from django.views import View
from .models import MenuItem, Category, OrderModel


class Index(View):
def get(self, request, *args, **kwargs):
    return render(request, 'customer/index.html')


class About(View):
def get(self, request, *args, **kwargs):
    return render(request, 'customer/about.html')


class Order(View):
def get(self, request, *args, **kwargs):
    # get every item from each category
    appetizers = MenuItem.objects.filter(
        category_name_contains='Appetizer')
    main_course = MenuItem.objects.filter(
        category_name_contains='Main Course')
    desserts = MenuItem.objects.filter(category_name_contains='Dessert')
    drinks = MenuItem.objects.filter(category_name_contains='Drink')

    # pass into context
    context = {
        'appetizers': appetizers,
        'main_course': main_course,
        'desserts': desserts,
        'drinks': drinks,
    }
    # render the templates
    return render(request, 'custormer/order.html', context)

def post(self, request, *args, **kwargs):
    order_items = {
        'items': []
    }

    items = request.POST.getlist('items[]')

    for item in items:
        menu_item = MenuItem.objects.get(pk=int(item))
        item_data = {
            'id': menu_item.pk,
            'name': menu_item.name,
            'price': menu_item.price
        }

        order_items['items'].append(item_data)

        price = 0
        item_ids = []

        for item in order_items['items']:
            price += item['price']
            item_ids.append(item['id'])

        order = OrderModel.objects.create(price=price)
        order.items.add(*item_ids)

        context = {
            'items': order_items['items'],
            'price': price

        }

        return render(request, 'customer/order_conformation.html', context)

This is my models.py:

from time import strftime
from unicodedata import category, name
from django.db import models


class MenuItem(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
image = models.ImageField(upload_to='menu_image/')
price = models.DecimalField(max_digits=5, decimal_places=2)
category = models.ManyToManyField('Category', related_name='item')

def __str__(self):
    return self.name


class Category(models.Model):
name = models.CharField(max_length=100)

def __str__(self):
    return self.name


class OrderModel(models.Model):
created_on = models.DateTimeField(auto_now_add=True)
price = models.DecimalField(max_digits=7, decimal_places=2)
items = models.ManyToManyField(
    'MenuItem', related_name='order', blank=True)

def __str__(self):
    return f'Order: {self.created_on.strftime("%b %d %I: %M %p")}'

Here's the traceback:

Traceback (most recent call last):
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\views\generic\base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\customer\views.py", line 
21, in get
appetizers = MenuItem.objects.filter(
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\query.py", line 1071, in filter
return self._filter_or_exclude(False, args, kwargs)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\query.py", line 1089, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\query.py", line 1096, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\sql\query.py", line 1502, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\sql\query.py", line 1532, in _add_q
child_clause, needed_inner = self.build_filter(
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\sql\query.py", line 1377, in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg)
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\sql\query.py", line 1187, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
File "C:\Users\Shreya\OneDrive\Desktop\li'lbites\littlebites\.venv\lib\site- 
packages\django\db\models\sql\query.py", line 1677, in names_to_path
raise FieldError(

Exception Type: FieldError at /order/
Exception Value: Cannot resolve keyword 'category_name_contains' into field. Choices 
are: category, description, id, image, name, order, price

So this my problem I have tried many solutions still not getting the problem here. As I can see that there is no problem in my core code but there is some internal issues, but still I can't run my program without solving them.

2 Answers

The error makes complete sense, it is because you have ManyToMany relation with your field category, and you are filtering through filter(category_name_contains) which is not right at all.

Field lookups required __ as a prefix not _. So it must be __contains.

You should use filter(category__name__contains='Appetizer') for every condition.

If you want to filter only through names, so you can simply filter with:

Views.py


class Order(View):
def get(self, request, *args, **kwargs):
    # get every item from each category
    appetizers = MenuItem.objects.filter(
        category__name__contains='Appetizer')
    main_course = MenuItem.objects.filter(
        category__name__contains='Main Course')
    desserts = MenuItem.objects.filter(category__name__contains='Dessert')
    drinks = MenuItem.objects.filter(category__name__contains='Drink')

    # pass into context
    context = {
        'appetizers': appetizers,
        'main_course': main_course,
        'desserts': desserts,
        'drinks': drinks,
    }
    # render the templates
    return render(request, 'custormer/order.html', context)

Note: ManyToManyField required its name to be defined as table_name with s to be the suffix, that means plural of table name. It will be better if you name it as categories instead of category in your MenuItem model.

Note: Models doesn't require model to be the suffix, so it will be better if you name it as Order instead of OrderModel.

You are almost there. You need to double the _ sign

category_name_contains to category_name__contains

Related