jazzband / django-eav2

Django EAV 2 - EAV storage for modern Django
https://django-eav2.readthedocs.io/
Other
334 stars 57 forks source link

Slugs with Hyphens Cannot Be Accessed via Entity __getattr__ #636

Closed Dresdn closed 2 weeks ago

Dresdn commented 2 weeks ago

Summary

When creating an Attribute in django-eav2 without specifying the slug, the default behavior is to use the package's generate_slug() function, which relies on Django's slugify utility. This often results in slugs containing hyphens, making it impossible to reference these attributes directly via the Entity class' __getattr__. Instead, developers are forced to use getattr() and setattr() methods as a workaround.

Steps to reproduce

  1. Create an Attribute with a name that results in a slug containing a hyphen:
    attr = Attribute.objects.create(name='Some Thing', datatype=Attribute.TYPE_TEXT)
  2. Create an instance of a model that uses the EAV manager:
    doc = Doctor.objects.create(name='Dr. Foo')
  3. Attempt to assign a value to the attribute using the EAV manager:
    doc.eav.some-thing = 'bar'

What is the current bug behavior?

A SyntaxError is raised, indicating that the hyphenated slug cannot be accessed or assigned using the dot notation:

>>> doc.eav.some-thing = 'bar'
  File "<console>", line 1
    doc.eav.some-thing = 'bar'
    ^^^^^^^^^^^^^^^^^^
SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?

What is the expected correct behavior?

The attribute should be accessible via the EAV manager using the dot notation, even if the slug contains a hyphen.

Relevant logs and/or screenshots

Here is an example traceback showing the issue:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File ".../django-eav2/eav/models/entity.py", line 65, in __getattr__
    raise AttributeError(
AttributeError: Doctor object has no EAV attribute named 'some'

Possible fixes

One potential solution is to modify the generate_slug() function to handle slugs with hyphens appropriately, allowing them to be accessed via the standard dot notation.