Hello,

- python version: 3.7
- django version: 2.2.16

After upgrading django from 2.2.15 to 2.2.16, I am experiencing errors with
the code shown below (see ----code----). Since 2.2.16 the
"getattr(self.original, field_name)" line results in the following stack
trace, which did not happen in 2.2.15:

--------stack trace---------
 File "/app/src/contrib/changed_model_fields/mixins.py", line 20, in save
    self.has_changed_fields(related_model)
  File "/app/src/contrib/changed_model_fields/mixins.py", line 44, in
has_changed_fields
    print(getattr(self.original, field_name))
  File
"/usr/local/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py",
line 189, in __get__
    "%s has no %s." % (self.field.model.__name__, self.field.name)
src.core.models.Variant.product.RelatedObjectDoesNotExist: Variant has no
product.
--------stack trace---------


The purpose of the "ChangedFieldMixin" is to determine if it contains any
modified (changed) attributes. The patch notes of 2.2.16
<https://docs.djangoproject.com/en/3.1/releases/2.2.16/> mentions
something, which I believe to be related to my issue:
https://code.djangoproject.com/ticket/31863


----------code------------

from copy import copy


class ChangedFieldMixin(object):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.original = copy(self)


    def save(self, related_model: ModelType = None, *args, **kwargs):
        force_changed_field = kwargs.pop('force_changed_field', False)

        if self.has_changed_fields(related_model):
            ...

        super().save(*args, **kwargs)

    def has_changed_fields(self, related_model: ModelType):
        for field in self._meta.fields:
            field_name = str(field.name)

            if not getattr(self, field_name) == getattr(self.original,
field_name):
                return True

        return False


class Variant(ChangedFieldMixin, models.Model):
    product = models.ForeignKey('Product', on_delete=models.CASCADE)
    code = models.CharField(max_length=255, null=True, blank=True)
    name = models.CharField(max_length=255, null=True, blank=True)
    key = models.CharField(max_length=255, unique=True, null=False,
blank=False)
    quantity = models.PositiveIntegerField(null=True, blank=True)
    default_price = models.PositiveIntegerField(default=None, null=True,
blank=True)

----------code------------

Is this expected behaviour now, or did the patch introduce a bug? Let me
know if I can provide additional information for the subject.


Thanks in advance

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAC%2BLcyiD9WQK9GX76d1seC%2Bq%2B0Oh%3DhO%3DCZx46-tUR2B-WCAALg%40mail.gmail.com.

Reply via email to