title: Django 3 Object Evaluation error due to from_db_value()
body: <p>I am attempting to update a project to Django 3 and I am running into a strange errors evaluating objects stating that:</p>
  
  <p><code>TypeError: from_db_value() missing 1 required positional argument: 'context'</code></p>
  
  <p>I read in the Django docs here: <a href="https://docs.djangoproject.com/en/3.0/releases/3.0/#features-removed-in-3-0" rel="nofollow noreferrer">https://docs.djangoproject.com/en/3.0/releases/3.0/#features-removed-in-3-0</a></p>
  
  <blockquote>
    <p>Support for the context argument of Field.from_db_value() and Expression.convert_value() is removed.</p>
  </blockquote>
  
  <p>But I am not understanding what I need to do to fix this, as my call is simply this to get the error...</p>
  
  <pre><code>apps = Application.objects.filter(completed=False, canceled=False)
  for app in apps:
      print(app)
  </code></pre>
  
  <p>Is there something I am not getting?</p>
  
  <p>Here is the full traceback, it seems to give me nothing to work with</p>
  
  <pre><code>Traceback (most recent call last):
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
  web_1       |     response = get_response(request)
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
  web_1       |     response = self.process_exception_by_middleware(e, request)
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
  web_1       |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
  web_1       |   File "/code/apps/users/decorators.py", line 23, in _wrapped_view
  web_1       |     return view_func(request, *args, **kwargs)
  web_1       |   File "/code/apps/users/decorators.py", line 23, in _wrapped_view
  web_1       |     return view_func(request, *args, **kwargs)
  web_1       |   File "/code/apps/reports/views/property_specific/availability_views.py", line 26, in availability_units_report
  web_1       |     for app in apps:
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 276, in __iter__
  web_1       |     self._fetch_all()
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 1261, in _fetch_all
  web_1       |     self._result_cache = list(self._iterable_class(self))
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 74, in __iter__
  web_1       |     for row in compiler.results_iter(results):
  web_1       |   File "/usr/local/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1095, in apply_converters
  web_1       |     value = converter(value, expression, connection)
  web_1       | TypeError: from_db_value() missing 1 required positional argument: 'context'
  </code></pre>
  
  <p><strong>Update</strong>
  Here is my associated Application Model if need be, although I see nothing in the 3.0 docs that I am declaring wrongly:</p>
  
  <pre><code>class Application(SafeDeleteModel, TimestampModel, UUID):
      class Meta:
          permissions = (
              ('view_ssn', 'Can view ssn'),
              ('change_ssn', 'Can change ssn'),
              ('waive_app_fee', 'Can waive app fee'),
              ('change_processing_management', 'Can change processing for management'),
              ('change_processing_compliance', 'Can change processing for compliance'),
              ('change_preleasing', 'Can change preleasing'),
              ('cancel_application', 'Can cancel application'),
              ('occupy_unit', 'Can occupy a unit'),
          )
  
      id = models.AutoField(primary_key=True)
  
      ...
      # I have no __str__ method for this model
  
  </code></pre>
  
  <p>Here is the inherited SafeDelete Model, built using <strong>django-safedelete</strong> <a href="https://github.com/makinacorpus/django-safedelete" rel="nofollow noreferrer">https://github.com/makinacorpus/django-safedelete</a></p>
  
  <pre><code>from safedelete.models import SafeDeleteModel as BaseModel
  
  class SafeDeleteModel(BaseModel):
      _safedelete_policy = SOFT_DELETE_CASCADE
  
      class Meta:
          abstract = True
          default_permissions = ('add', 'change', 'delete', 'view', 'undelete')
  
      def exclude(self, value):
          Logger.info(self)
  
      def update(self, new_dict):
          """
          Update object with form field dictionary on submission.
          :param new_dict:
          """
          fields = [x.name for x in self._meta.get_fields()]
          for key, value in new_dict.items():
              if key in fields:
                  setattr(self, key, value)
  </code></pre>
  
  <p>My timestamp and UUID inherited models simply add UUID and Timestamp fields to my models in a more universal manner, there is no need to show them.</p>
  
  <p>Here is BaseModel, but it just comes from the SafeDeleteModel so I could add a tiny bit more functionality.</p>
  
  <pre><code>class SafeDeleteModel(models.Model):
      """Abstract safedelete-ready model.
  
      .. note::
          To create your safedelete-ready models, you have to make them inherit from this model.
  
      :attribute deleted:
          DateTimeField set to the moment the object was deleted. Is set to
          ``None`` if the object has not been deleted.
  
      :attribute _safedelete_policy: define what happens when you delete an object.
          It can be one of ``HARD_DELETE``, ``SOFT_DELETE``, ``SOFT_DELETE_CASCADE``, ``NO_DELETE`` and ``HARD_DELETE_NOCASCADE``.
          Defaults to ``SOFT_DELETE``.
  
          &gt;&gt;&gt; class MyModel(SafeDeleteModel):
          ...     _safedelete_policy = SOFT_DELETE
          ...     my_field = models.TextField()
          ...
          &gt;&gt;&gt; # Now you have your model (with its ``deleted`` field, and custom manager and delete method)
  
      :attribute objects:
          The :class:`safedelete.managers.SafeDeleteManager` that returns the non-deleted models.
  
      :attribute all_objects:
          The :class:`safedelete.managers.SafeDeleteAllManager` that returns the all models (non-deleted and soft-deleted).
  
      :attribute deleted_objects:
          The :class:`safedelete.managers.SafeDeleteDeletedManager` that returns the soft-deleted models.
      """
  
      _safedelete_policy = SOFT_DELETE
  
      deleted = models.DateTimeField(editable=False, null=True)
  
      objects = SafeDeleteManager()
      all_objects = SafeDeleteAllManager()
      deleted_objects = SafeDeleteDeletedManager()
  
      class Meta:
          abstract = True
  
      def save(self, keep_deleted=False, **kwargs):
          """Save an object, un-deleting it if it was deleted.
  
          Args:
              keep_deleted: Do not undelete the model if soft-deleted. (default: {False})
              kwargs: Passed onto :func:`save`.
  
          .. note::
              Undeletes soft-deleted models by default.
          """
  
          # undelete signal has to happen here (and not in undelete)
          # in order to catch the case where a deleted model becomes
          # implicitly undeleted on-save.  If someone manually nulls out
          # deleted, it'll bypass this logic, which I think is fine, because
          # otherwise we'd have to shadow field changes to handle that case.
  
          was_undeleted = False
          if not keep_deleted:
              if self.deleted and self.pk:
                  was_undeleted = True
              self.deleted = None
  
          super(SafeDeleteModel, self).save(**kwargs)
  
          if was_undeleted:
              # send undelete signal
              using = kwargs.get('using') or router.db_for_write(self.__class__, instance=self)
              post_undelete.send(sender=self.__class__, instance=self, using=using)
  
      def undelete(self, force_policy=None, **kwargs):
          """Undelete a soft-deleted model.
  
          Args:
              force_policy: Force a specific undelete policy. (default: {None})
              kwargs: Passed onto :func:`save`.
  
          .. note::
              Will raise a :class:`AssertionError` if the model was not soft-deleted.
          """
          current_policy = force_policy or self._safedelete_policy
  
          assert self.deleted
          self.save(keep_deleted=False, **kwargs)
  
          if current_policy == SOFT_DELETE_CASCADE:
              for related in related_objects(self):
                  if is_safedelete_cls(related.__class__) and related.deleted:
                      related.undelete()
  
      def delete(self, force_policy=None, **kwargs):
          """Overrides Django's delete behaviour based on the model's delete policy.
  
          Args:
              force_policy: Force a specific delete policy. (default: {None})
              kwargs: Passed onto :func:`save` if soft deleted.
          """
          current_policy = self._safedelete_policy if (force_policy is None) else force_policy
  
          if current_policy == NO_DELETE:
  
              # Don't do anything.
              return
  
          elif current_policy == SOFT_DELETE:
  
              # Only soft-delete the object, marking it as deleted.
              self.deleted = timezone.now()
              using = kwargs.get('using') or router.db_for_write(self.__class__, instance=self)
              # send pre_softdelete signal
              pre_softdelete.send(sender=self.__class__, instance=self, using=using)
              super(SafeDeleteModel, self).save(**kwargs)
              # send softdelete signal
              post_softdelete.send(sender=self.__class__, instance=self, using=using)
  
          elif current_policy == HARD_DELETE:
  
              # Normally hard-delete the object.
              super(SafeDeleteModel, self).delete()
  
          elif current_policy == HARD_DELETE_NOCASCADE:
  
              # Hard-delete the object only if nothing would be deleted with it
  
              if not can_hard_delete(self):
                  self.delete(force_policy=SOFT_DELETE, **kwargs)
              else:
                  self.delete(force_policy=HARD_DELETE, **kwargs)
  
          elif current_policy == SOFT_DELETE_CASCADE:
              # Soft-delete on related objects before
              for related in related_objects(self):
                  if is_safedelete_cls(related.__class__) and not related.deleted:
                      related.delete(force_policy=SOFT_DELETE, **kwargs)
              # soft-delete the object
              self.delete(force_policy=SOFT_DELETE, **kwargs)
  
      @classmethod
      def has_unique_fields(cls):
          """Checks if one of the fields of this model has a unique constraint set (unique=True)
  
          Args:
              model: Model instance to check
          """
          for field in cls._meta.fields:
              if field._unique:
                  return True
          return False
  
      # We need to overwrite this check to ensure uniqueness is also checked
      # against "deleted" (but still in db) objects.
      # FIXME: Better/cleaner way ?
      def _perform_unique_checks(self, unique_checks):
          errors = {}
  
          for model_class, unique_check in unique_checks:
              lookup_kwargs = {}
              for field_name in unique_check:
                  f = self._meta.get_field(field_name)
                  lookup_value = getattr(self, f.attname)
                  if lookup_value is None:
                      continue
                  if f.primary_key and not self._state.adding:
                      continue
                  lookup_kwargs[str(field_name)] = lookup_value
              if len(unique_check) != len(lookup_kwargs):
                  continue
  
              # This is the changed line
              if hasattr(model_class, 'all_objects'):
                  qs = model_class.all_objects.filter(**lookup_kwargs)
              else:
                  qs = model_class._default_manager.filter(**lookup_kwargs)
  
              model_class_pk = self._get_pk_val(model_class._meta)
              if not self._state.adding and model_class_pk is not None:
                  qs = qs.exclude(pk=model_class_pk)
              if qs.exists():
                  if len(unique_check) == 1:
                      key = unique_check[0]
                  else:
                      key = models.base.NON_FIELD_ERRORS
                  errors.setdefault(key, []).append(
                      self.unique_error_message(model_class, unique_check)
                  )
          return errors
  
  </code></pre>
  
  <p>And here is SafeDeleteManager for the model manager:</p>
  
  <pre><code>class SafeDeleteManager(models.Manager):
      """Default manager for the SafeDeleteModel.
  
      If _safedelete_visibility == DELETED_VISIBLE_BY_PK, the manager can returns deleted
      objects if they are accessed by primary key.
  
      :attribute _safedelete_visibility: define what happens when you query masked objects.
          It can be one of ``DELETED_INVISIBLE`` and ``DELETED_VISIBLE_BY_PK``.
          Defaults to ``DELETED_INVISIBLE``.
  
          &gt;&gt;&gt; from safedelete.models import SafeDeleteModel
          &gt;&gt;&gt; from safedelete.managers import SafeDeleteManager
          &gt;&gt;&gt; class MyModelManager(SafeDeleteManager):
          ...     _safedelete_visibility = DELETED_VISIBLE_BY_PK
          ...
          &gt;&gt;&gt; class MyModel(SafeDeleteModel):
          ...     _safedelete_policy = SOFT_DELETE
          ...     my_field = models.TextField()
          ...     objects = MyModelManager()
          ...
          &gt;&gt;&gt;
  
      :attribute _queryset_class: define which class for queryset should be used
          This attribute allows to add custom filters for both deleted and not
          deleted objects. It is ``SafeDeleteQueryset`` by default.
          Custom queryset classes should be inherited from ``SafeDeleteQueryset``.
      """
  
      _safedelete_visibility = DELETED_INVISIBLE
      _safedelete_visibility_field = 'pk'
      _queryset_class = SafeDeleteQueryset
  
      def __init__(self, queryset_class=None, *args, **kwargs):
          """Hook for setting custom ``_queryset_class``.
  
          Example:
  
              class CustomQueryset(models.QuerySet):
                  pass
  
              class MyModel(models.Model):
                  my_field = models.TextField()
  
                  objects = SafeDeleteManager(CustomQuerySet)
          """
          super(SafeDeleteManager, self).__init__(*args, **kwargs)
          if queryset_class:
              self._queryset_class = queryset_class
  
      def get_queryset(self):
          # Backwards compatibility, no need to move options to QuerySet.
          queryset = self._queryset_class(self.model, using=self._db)
          queryset._safedelete_visibility = self._safedelete_visibility
          queryset._safedelete_visibility_field = self._safedelete_visibility_field
          return queryset
  
      def all_with_deleted(self):
          """Show all models including the soft deleted models.
  
          .. note::
              This is useful for related managers as those don't have access to
              ``all_objects``.
          """
          return self.all(
              force_visibility=DELETED_VISIBLE
          )
  
      def deleted_only(self):
          """Only show the soft deleted models.
  
          .. note::
              This is useful for related managers as those don't have access to
              ``deleted_objects``.
          """
          return self.all(
              force_visibility=DELETED_ONLY_VISIBLE
          )
  
      def all(self, **kwargs):
          """Pass kwargs to ``SafeDeleteQuerySet.all()``.
  
          Args:
              force_visibility: Show deleted models. (default: {None})
  
          .. note::
              The ``force_visibility`` argument is meant for related managers when no
              other managers like ``all_objects`` or ``deleted_objects`` are available.
          """
          force_visibility = kwargs.pop('force_visibility', None)
  
          # We don't call all() on the queryset, see https://github.com/makinacorpus/django-safedelete/issues/81
          qs = self.get_queryset()
          if force_visibility is not None:
              qs._safedelete_force_visibility = force_visibility
          return qs
  
      def update_or_create(self, defaults=None, **kwargs):
          """See :func:`~django.db.models.Query.update_or_create.`.
  
          Change to regular djangoesk function:
          Regular update_or_create() fails on soft-deleted, existing record with unique constraint on non-id field
          If object is soft-deleted we don't update-or-create it but reset the deleted field to None.
          So the object is visible again like a create in any other case.
  
          Attention: If the object is "revived" from a soft-deleted state the created return value will
          still be false because the object is technically not created unless you set
          SAFE_DELETE_INTERPRET_UNDELETED_OBJECTS_AS_CREATED = True in the django settings.
  
          Args:
              defaults: Dict with defaults to update/create model instance with
              kwargs: Attributes to lookup model instance with
          """
  
          # Check if one of the model fields contains a unique constraint
          revived_soft_deleted_object = False
          if self.model.has_unique_fields():
              # Check if object is already soft-deleted
              deleted_object = self.all_with_deleted().filter(**kwargs).exclude(deleted=None).first()
  
              # If object is soft-deleted, reset delete-state...
              if deleted_object and deleted_object._safedelete_policy in self.get_soft_delete_policies():
                  deleted_object.deleted = None
                  deleted_object.save()
                  revived_soft_deleted_object = True
  
          # Do the standard logic
          obj, created = super(SafeDeleteManager, self).update_or_create(defaults, **kwargs)
  
          # If object was soft-deleted and is "revived" and settings flag is True, show object as created
          if revived_soft_deleted_object and \
                  getattr(settings, 'SAFE_DELETE_INTERPRET_UNDELETED_OBJECTS_AS_CREATED', False):
              created = True
  
          return obj, created
  
      @staticmethod
      def get_soft_delete_policies():
          """Returns all stati which stand for some kind of soft-delete"""
          return [SOFT_DELETE, SOFT_DELETE_CASCADE]
  
  </code></pre>