Search code examples
djangomongodbmodeldjongo

Djongo ArrayField 'Item' is not subscriptable


I have 2 models in my django project. DB is mongoDB and I use Djongo.

Here are the models:

class Item(models.Model):
    item_id = models.IntegerField(primary_key=True)
    item_name = models.CharField(max_length=30)

    def __str__(self):
        return f'<{self.item_name}>'


class Items(models.Model):
    items_id = models.IntegerField(primary_key=True)
    inventory = models.ArrayField(model_container=Item,)
    neutral_item = models.EmbeddedField(model_container=Item,)
    buffs = models.ArrayField(model_container=Item,)

    def __str__(self):
        return f'<{self.inventory}, {self.neutral_item}>'

When I do:

item = Item(item_name='Helmet')
items = Items(inventory=[item])

I am getting this TypeError:

'Item' object is not subscriptable

What is wrong?

Whole error message:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/base.py", line 745, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/base.py", line 782, in save_base
    updated = self._save_table(
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/base.py", line 887, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/base.py", line 924, in _do_insert
    return manager._insert(
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/query.py", line 1204, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1390, in execute_sql
    for sql, params in self.as_sql():
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1333, in as_sql
    value_rows = [
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1334, in <listcomp>
    [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1334, in <listcomp>
    [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1275, in prepare_value
    value = field.get_db_prep_save(value, connection=self.connection)
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/djongo/models/fields.py", line 215, in get_db_prep_save
    return self.get_prep_value(value)
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/djongo/models/fields.py", line 222, in get_prep_value
    processed_value = self._value_thru_fields('get_prep_value',
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/djongo/models/fields.py", line 315, in _value_thru_fields
    post_dict = super()._value_thru_fields(func_name,
  File "/Users/georgii/PycharmProjects/custom_hero_chaos/venv/lib/python3.8/site-packages/djongo/models/fields.py", line 145, in _value_thru_fields
    field_value = value[field.attname]
TypeError: 'Item' object is not subscriptable

Solution

  • According to the Djongo docs for ArrayField you should instantiate like this:

    entry = Entry()
    entry.authors = [{'name': 'John', 'email': '[email protected]'},
                    {'name': 'Paul', 'email': '[email protected]'}]
    entry.save()
    

    So in your case, you would do this.

    items = Items()
    items.inventory = [
        {'item_name': 'Helmet'}
    ]
    items.save()