GithubHelp home page GithubHelp logo

jazzband / django-eav2 Goto Github PK

View Code? Open in Web Editor NEW
337.0 337.0 57.0 1.67 MB

Django EAV 2 - EAV storage for modern Django

Home Page: https://django-eav2.readthedocs.io/

License: Other

Python 100.00%
django django-eav2 eav-model entity-attribute

django-eav2's People

Contributors

954-ivory avatar arhell avatar cclauss avatar cocorocho avatar cv3d avatar danielindictor avatar dependabot[bot] avatar dgelvin avatar dorey avatar dresdn avatar iamanikeev avatar iwoherka avatar jacobjove avatar jayvdb avatar jazzband-bot avatar jezdez avatar jpwhite3 avatar kiraware avatar lvm avatar majekx avatar mathiasag7 avatar nicpottier avatar pre-commit-ci[bot] avatar puyup avatar radalin avatar tavaresb avatar thedavidmccann avatar timlinux avatar tmladek avatar zachtaylor21 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-eav2's Issues

Filtering object types

I'm trying to filter based on the object type. Usage for "simple" attributes are like this:

MyModel.objects.filter(eav__custom_attr=2)

However when using the same notation for objects:

MyModel.objects.filter(eav__custom_obj=2)

It throws the following error:

Field 'value_object' does not generate an automatic reverse relation and therefore cannot be used for reverse querying. If it is a GenericForeignKey, consider adding a GenericRelation.

Expected Behavior

Usage of the following lines should provide a list of filtered objects

MyModel.objects.filter(eav__custom_obj=2)

Actual Behavior

Throws an exception.

Possible Fix

Syntax of how this can be done can be added to the readme if it's possible (or it could say it's not supported yet).

Something like this can be implemented:

MyModel.objects.filter(eav__custom_obj__pk=2)

Your Environment

  • Version used: 0.13.0
  • Environment name and version: Django 2.2.2, Python 3.7.5
  • Operating System and version: Mac OS

Install creates global package "tests"

Currently setup.py is declaring packages called "eav" and "tests" - the latter one will cause problems, since it means you're installing to

site-packages/eav/
site-packages/tests/

So if any other package is doing the same you'll hit the same "tests" package (and uninstalling either will delete the shared directory.

Instead you probably just want packages=["eav"] (you don't need installers of your package to install your tests).

Consider adding model validation to Entity

Some ValidationErrors thrown in entity's save() method are user preventable, for example:

  1. EAV field cannot be blank
  2. %(enum)s is not a valid choice
  3. There are also custom Attribute validators.

In addition to having them as the last-resort validation in the save() method, these could also be added to Django's model clean methods in order to make the errors visible to the user on form save:
https://docs.djangoproject.com/en/2.0/ref/models/instances/#validating-objects

In case that the current validation works (i.e. does not throw 500 errors in the django admin or test form), the question is - how was that implemented? ValidationErrors are not catched in Django after is_valid() finishes.

get_values() and get_values_dict() returns different type for enum

why not returning the value of the enum element in get_values()? so that we have a dictionary that ca be used to print attributes easily?
As of now I need to always test for enum element in my templates:
{% for obj in sample.eav.get_values %}
{{ obj.attribute.name }}:{% if obj.value.value %}{{ obj.value.value }}{% else %}{{ obj.value }}{% endif %}
{% endfor %}

Am I missing something?

Implement Jazzband guidelines for django-eav2

This issue tracks the implementation of the Jazzband guidelines for the project django-eav2

It was initiated by @lvm who was automatically assigned in addition to the Jazzband roadies.

See the TODO list below for the generally required tasks, but feel free to update it in case the project requires it.

Feel free to ping a Jazzband roadie if you have any question.

TODOs

Project details

Description Django EAV 2 - EAV storage for modern Django
Homepage https://django-eav2.readthedocs.io/
Stargazers 98
Open issues 15
Forks 31
Default branch master
Is a fork False
Has Wiki True
Has Pages False

Eav registered model can't use defaults attr at get_or_create method

Expected Behavior

@register_eav

class Supplier(models.Model):
   ....

Supplier.objects.get_or_create(
    foo='bar',
    defaults={'some_field': 'Some_value'}
)

Expected, that it will work

Actual Behavior

File "/Users/timurodintsov/.pyenv/versions/zip_test_web_3.9.1/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1483, in names_to_path raise FieldError("Cannot resolve keyword '%s' into field. " django.core.exceptions.FieldError: Cannot resolve keyword 'defaults' into field. Choices are:

Your Environment

Include relevant details about the environment you experienced the bug in.

Mac OS X
Django==3.0.7
django-eav2==0.13.0

Django 3.1 FieldDoesNotExist

It is now only in django.core.exceptions.

  File "/usr/lib/python3.8/site-packages/eav/queryset.py", line 179, in wrapper
    nkey, nval = expand_eav_filter(self.model, key, value)
  File "/usr/lib/python3.8/site-packages/eav/queryset.py", line 251, in expand_eav_filter
    except models.FieldDoesNotExist:
AttributeError: module 'django.db.models' has no attribute 'FieldDoesNotExist'

eav table(s) aren't created (eav app not detected?)

I'm not sure what I'm doing wrong, but the eav_attribute table isn't being created in my database when I run manage migrate.

Maybe I'm missing a setup step?

Steps to reproduce:

(with a fresh virtualenv, python3.6, on Ubuntu)

pip install django~=1.11.14 django-eav2~=0.11.0
django-admin startproject scratch
cd scratch
django-admin startapp foo
# create a simple models.py
cat << EOF > foo/models.py
from django.db import models
import eav

class Foo(models.Model):
    body = models.IntegerField()

eav.register(Foo)
EOF
# then enable contrib.sites (required?) and add eav and my `foo` app to scratch/settings.py :
INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.sites',
    'django.contrib.admin',
    'django.contrib.contenttypes',
    "eav",
    "foo",
]

SITE_ID = 1

and

./manage.py makemigrations
./manage.py migrate

outputs:

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, foo, sites
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying foo.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK

Note that manage migrate doesn't create an eav_attribute table, and therefore the following fails with "django.db.utils.OperationalError: no such table: eav_attribute"

from eav.models import Attribute
Attribute.objects.create(name='City', datatype=Attribute.TYPE_TEXT)

I fee like I'm doing something stupid, but I don't see what it is.

NullBooleanField is deprecated

Provide a general summary of the issue in the title above.
Django 3.1.2 gives a deprecation warning when running the eav.0001_initial migration:

eav.Value.value_bool: (fields.W903) NullBooleanField is deprecated. Support for it (except in historical migrations) will be removed in Django 4.0.
HINT: Use BooleanField(null=True) instead.

Expected Behavior

Shouldn't get deprecation warning

Actual Behavior

Got deprecation warning

Possible Fix

Replace NullBooleanField with BooleanField(null=True) as the deprecation warning recommends.

Steps to Reproduce

  1. Install Django 3.1.2
  2. Install django-eav2
  3. Add 'eav' to INSTALLED_APPS
  4. Run python manage.py migrate.

Your Environment

Linux, using Django 3.1.2

  • Version used: 0.13.0
  • Environment name and version (e.g. Django 2.0.4, pip 9.0.1): Django 3.1.2
  • Operating System and version: Ubuntu 18.04
  • Link to your project (if applicable):

filter eav attribute in related field?

when I try to filter a classifier that has a measure with an eav attribute like below:
Classifier.objects.filter(measure__eav__through_packaging=False)

I get the following error:
django.core.exceptions.FieldError: Related Field got invalid lookup: eav

is it normal?

Value assignments to attributes excluded for entity are silently ignored

Overriding EavConfig class when registering Entity allows the end-user to limit attributes which are "visible" to the Entity instance (registered model):

class SuppliersEavConfig(EavConfig):
    @classmethod
    def get_attributes(cls):
        return Attribute.objects.filter(slug__contains='a')

This causes assignments such as:

supplier.eav.height = 3

to be silently ignored upon save.

This a useful feature, however, arguably, the whole point is to disallow certain assignments. Therefore,
if an assignment takes place, it is safe to assume that something went wrong and validation should scream, like it normally does.

What do you think? @maticomp @dragonee
If there are no objections, I will make issue for the fix.

Add tools for migrating EAV values from EAV structure into table attributes (maybe even without breaking compatibility)

Most of the problem with EAV structures is that they are not maintained properly. The concrete problem is the following situation:

  • project enters maturity
  • new features being added depend on a specific Attribute
  • there is a fear of changing existing EAV not to break the existing structure
  • a decision is made for the Attribute to stay in EAV. The complexity accumulates.

The idea is to reduce fear of change by introducing tools that would reduce points of failure in the code.

Detailed Description

There are two tools that can be useful to enable The first one is a dedicated tool to make a migration from EAV to a concrete field on an Entity. In more complicated cases, some method can be overridden in a migration to save all Values in the desired places.

In addition, if that's possible, there could be a way to proxy eav access (by filters and .eav API) to these attributes by a delegate setting on EavConfig.

Context

In a best possible scenario, as an user I would do three steps to refactor EAV Attribute out of EAV system:

  1. Create a new attribute on model.
  2. Create a data migration (automatically) and run it.
  3. Add a delegate setting on EavConfig on a model.

After this, no code is broken and the system uses standard QuerySet/Model API even if it is prefixed by eav in the code.

django.db.utils.IntegrityError: NOT NULL constraint failed: eav_attribute.site_id

Provide a general summary of the issue in the title above.

I got the below error after while creating attribute
Attribute.objects.create(name='email', datatype=Attribute.TYPE_TEXT )

File "/home/ewall-hp2/Documents/Django-Normal/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/ewall-hp2/Documents/Django-Normal/lib/python3.6/site-packages/django/db/utils.py", line 89, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/ewall-hp2/Documents/Django-Normal/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/ewall-hp2/Documents/Django-Normal/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: eav_attribute.site_id

DJango 2.2

Multiple choice field should be able to be null if not required

I created a multiple choice field and marked it as not required, but the admin throws an exception whenever I leave it blank in my model. The error is

eav.models.EnumValue.DoesNotExist: EnumValue matching query does not exist.

and occurs on line 534 of models.py.

Expected Behavior

The admin should not throw an exception when I leave a not-required multiple choice field blank.

Actual Behavior

The admin throws an exception when I leave a not-required multiple choice field blank.

Possible Fix

Replace line 534 of models.py with

- attribute_value = EnumValue.objects.get(value=attribute_value)
+ if attribute_value is not None:
+     attribute_value = EnumValue.objects.get(value=attribute_value)

Steps to Reproduce

  1. Create a model and register it with eav
  2. Go to the admin and create a multiple choice field, and mark it as not required
  3. Go to the admin page for the model created in step 1 and click the button to create a new model
  4. Make sure the multiple choice field is set to ----- and click save.

Your Environment

Brand new project created with Django 3.1.2

  • Version used: 0.13.0
  • Environment name and version (e.g. Django 2.0.4, pip 9.0.1): Django 3.1.2
  • Operating System and version: Ubuntu 18.04
  • Link to your project (if applicable):

how to access attribute fields properties in BaseDynamicEntityForm?

I have a form for my model Sample which contains attributes:

class SampleForm(BaseDynamicEntityForm):
    def __init__(self, *args, **kwargs):
        self.request_user = kwargs.pop('request_user')
        self.sample = kwargs.pop('sample')
        kwargs.setdefault('label_suffix', '')
        super(SampleForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Sample
        fields = [
            'name',
        ]

I would like to override the choices of one of my eav attributes which is a Multiple Choice in order to show only part of the choices depending on the user.

with the normal forms.ModelForm I could define the field choices in my init function with:
self.fields['eav_attribute_name'].choices = choices_subset

but it does not work with BaseDynamicEntityForm.

Any suggestion?

thanks a lot for the great work.

same thing I would like to show only some of the attributes in the form depending on the user or on other properties of the main object sample. How could I?

Fix tests for Django 2.1+

Traceback (most recent call last):
  File "/home/siegmeyer/Code/django-eav2/runtests", line 28, in <module>
    result = test_runner.run_tests(tests)
  File "/home/siegmeyer/Code/django-eav2/.tox/py35-djangotip/lib/python3.5/site-packages/django/test/runner.py", line 603, in run_tests
    suite = self.build_suite(test_labels, extra_tests)
  File "/home/siegmeyer/Code/django-eav2/.tox/py35-djangotip/lib/python3.5/site-packages/django/test/runner.py", line 485, in build_suite
    tests = self.test_loader.loadTestsFromName(label)
  File "/usr/lib/python3.5/unittest/loader.py", line 153, in loadTestsFromName
    module = __import__(module_name)
  File "/home/siegmeyer/Code/django-eav2/tests/forms.py", line 5, in <module>
    from eav.admin import *
  File "/home/siegmeyer/Code/django-eav2/eav/admin.py", line 83, in <module>
    admin.site.register(Attribute, AttributeAdmin)
  File "/home/siegmeyer/Code/django-eav2/.tox/py35-djangotip/lib/python3.5/site-packages/django/utils/functional.py", line 213, in inner
    self._setup()
  File "/home/siegmeyer/Code/django-eav2/.tox/py35-djangotip/lib/python3.5/site-packages/django/contrib/admin/sites.py", line 526, in _setup
    AdminSiteClass = import_string(apps.get_app_config('admin').default_site)
  File "/home/siegmeyer/Code/django-eav2/.tox/py35-djangotip/lib/python3.5/site-packages/django/apps/registry.py", line 159, in get_app_config
    raise LookupError(message)
LookupError: No installed app with label 'admin'.

This error is thrown by admin.site.register(Attribute, AttributeAdmin) in eav/admin.py.

Cannot add EAV attributes to a custom user model

I have a custom user model according to instructions here https://docs.djangoproject.com/en/2.1/topics/auth/customizing/ and would like to add user customisable attributes to the user model with django-eav2. In other areas of my project EAV attributes work as expected, but with custom user model (inherited from django.contrib.auth.models.AbstractUser) python manage.py makemigrations users fail with an error.

Expected Behavior

python manage.py makemigrations users is successful and migration files are generated.

Actual Behavior

python manage.py makemigrations users fails with following error and stacktrace:

(abstractusertest) pormb:abstractusertest por$ python manage.py makemigrations users
Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/django/core/management/__init__.py", line 357, in execute
    django.setup()
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/django/apps/registry.py", line 112, in populate
    app_config.import_models()
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/django/apps/config.py", line 198, in import_models
    self.models_module = import_module(models_module_name)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/por/Projects/abstractusertest/abstractusertest/users/models.py", line 8, in <module>
    class User( django.contrib.auth.models.AbstractUser ):
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/eav/decorators.py", line 21, in _model_eav_wrapper
    register(model_class, **kwargs)
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/eav/__init__.py", line 5, in register
    Registry.register(model_cls, config_cls)
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/eav/registry.py", line 70, in register
    reg._register_self()
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/eav/registry.py", line 182, in _register_self
    self._attach_manager()
  File "/Users/por/Projects/abstractusertest/lib/python3.7/site-packages/eav/registry.py", line 111, in _attach_manager
    self.model_cls._meta.local_managers.remove(mgr)
ValueError: list.remove(x): x not in list

Additionally, if I enable EAV for User model, migrations of all other EAV'd models start failing with same error. If I remove traces of EAV from user model, other models work fine and EAV works fine.

Steps to Reproduce

Test project attached

  • Create a virtualenv (Python 3)
  • Unpack attached file
  • pip install -r requirements.txt
  • python manage.py makemigrations users

Your Environment

Mac OS X
Django==2.1.3
django-eav2==0.11.1

abstractusertest.tar.gz

Add support for full QuerySet API

As of right now, only basic QuerySet methods are supported for EAV values, namely:
filter, exclude and get. Therefore, something like:

Patient.objects.all().order_by('eav__date_of_admission')

will not work.

It would be useful to add support for the full QuerySet API.

Is the BaseDynamicEntityForm commit=True implementation breaking compatibility with Django form?

In the default Django ModelForm's implementation, commit=True implies form.save_m2m().

See: https://github.com/django/django/blob/master/django/forms/models.py#L456 :

    if commit:
            # If committing, save the instance and the m2m data immediately.
            self.instance.save()
            self._save_m2m()

However, the BaseDynamicEntityForm overrides the save and does nothing to save many to many implementations - it must be called manually afterwards, which is not consistent with the default behaviour.

instance = super(BaseDynamicEntityForm, self).save(commit=False)

# ...

 if commit:
            instance.save()

Should it be changed? I do not know what happens if save_m2m() is called twice so it could possibly break backwards compatibility with earlier implementations.

TypeError __init__() got an unexpected keyword argument 'max_length'

Provide a general summary of the issue in the title above.

Expected Behavior

Show add attribute value form

Actual Behavior

Return TypeError __init__() got an unexpected keyword argument 'max_length'

Possible Fix

Not obligatory, but you can suggest a fix or reason for the bug.

Steps to Reproduce

Just install v0.14.0 then open admin page navigate to EAV -> Value -> Add

Your Environment

Include relevant details about the environment you experienced the bug in.

  • Version used: 0.14.0
  • Environment name and version: Django 3.2.7
  • Operating System and version: Windows 10

Improve and revamp test-suite

We should go over test-suite in order to:

  1. Clean-up old tests (code style is lacking)
  2. Evaluate present test-cases and add missing ones where applicable
  3. Add more tests for admin and forms which are dragging down our coverage percentage (see codacy). It would be nice to bump our coverage by 5% to 95% or more.
  4. Possibly migrate them to pytest. It should not take too long.

Consider adding pre-commit.yml

Detailed Description

This issue is to add pre-commit.yml hooks to this project.
There are a few that I think can be interesting:

  • github.com/ecugol/pre-commit-hooks-django (as the name suggests...)
  • github.com/psf/black (runs black on the project)
  • github.com/pre-commit/pre-commit-hooks (plus a bunch from this default repo)

Context

This is relevant since it has been enabled automatically in all jazzband repos.

Possible Implementation

There's a discussion in the jazzband orga about this: https://github.com/orgs/jazzband/teams/members/discussions/18

Make it possible to have Attributes only apply to one model

Detailed Description

Sometimes it would be handy to be able to limit Attributes to only one model. I would add an optional FK from Attribute to ContentType, like there already is on the Value table.

Context

How would I use this? Well say I have a model called Car and another called Movie. The Attribute "color" makes sense for Car instances, but not for Movie instances. With the Attribute "duration" it is the other way around; it makes sense for Movie instances, but not for Car instances.

Possible Implementation

See tykling@dd27836
Let me know if you want a PR

DRF support

It would be great if there was a generic/basic DRF implementation provided here, perhaps as "contrib" if not core.

It would be wise to avoid design it so that it is usable by everyone, but it would outline the structure to follow for people that needed to create their own more specialised one, and probably provide some of the classes they need.

If interested, I have a basic DRF implementation which isnt generic yet, but it wouldnt be too difficult for me to split off the custom bits to create a generic implementation.

module 'django.db.models' has no attribute 'FieldDoesNotExist'

After upgrading to Django 3.1 from Django 3.0.8 I get this error:

module 'django.db.models' has no attribute 'FieldDoesNotExist'
/usr/local/lib/python3.7/site-packages/eav/queryset.py, line 179, in wrapper
nkey, nval = expand_eav_filter(self.model, key, value) …

/usr/local/lib/python3.7/site-packages/eav/queryset.py, line 251, in expand_eav_filter
except models.FieldDoesNotExist: …

Clean-up old codebase

  • Move license notices out of the code
  • Remove Vim directives
  • Clean-up and polish doc-strings

Add short explanation at the top of the README/documentation

For example:

Entity-Attribute-Value is a database structure that is used primarily under these conditions:

  1. Model attributes are to be added and removed by end users (or are unknowable in some different way). EAV supports these without ALTER TABLE statements and allows the attributes to be strongly typed and easily searchable.
  2. There will be many attributes and values are sparse, in contrast to having tables with mostly-null columns.
  3. In most cases the same logic will be applied to handling each attribute (if too much of the application code depends on the specific attribute, you should consider moving it as a model attribute or a new model in your codebase).

The most common use case for EAV are custom product attributes in ecommerce implementations.
Note: It's very important NOT to overuse EAV - especially regarding to the third point above.

Entities are your typical Django model instances. Attributes (name and type) are stored in their own table, which makes it easy to manipulate the list of available attributes in the system. Values are an intermediate table between attributes and entities, each instance holding a single value.
This implementation also makes it easy to edit attributes in Django Admin and form instances.

0.13 to master fails - django.db.utils.ProgrammingError: relation "eav_attribute_entity_ct" does not exist

Provide a general summary of the issue in the title above.

Moving from the latest tag (0.13) to the master branch breaks with:

django.db.utils.ProgrammingError: relation "eav_attribute_entity_ct" does not exist
LINE 1: ...pe"."model" FROM "django_content_type" INNER JOIN "eav_attri...

This is related to #59 where the migration to create the entity_ct field isn't executed as the 0001_initial migration already executed.

Expected Behavior

Field entity_ct to be created by migration.

Actual Behavior

Migration isn't executed.

Possible Fix

Create a proper migration - PR coming.

Steps to Reproduce

  1. Install latest tag
  2. Upgrade to head

Your Environment

Include relevant details about the environment you experienced the bug in.

  • Version used:
  • Environment name and version (e.g. Django 2.0.4, pip 9.0.1): Django 3.1.5
  • Operating System and version:
  • Link to your project (if applicable):

Missing Migration in v0.11.1?

When running python manage.py makemigrations EAV produces an additional migration.

Expected Behavior

All required migrations are released.

Actual Behavior

An additional migration is generated.

Steps to Reproduce

Install django-eav2==0.11.1 and run python manage.py makemigrations

Your Environment

  • Version used: 0.11.1
  • Django 2.1.4
  • Linux 2ae9fa07bf9c 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux (Python 3.6 Docker Image)

Thank you for taking time to look at this.


I've pasted the generated migration below:

# Generated by Django 2.1.4 on 2019-01-19 00:21

from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import eav.fields


class Migration(migrations.Migration):

    dependencies = [("eav", "0001_initial")]

    operations = [
        migrations.AlterField(
            model_name="attribute",
            name="created",
            field=models.DateTimeField(
                default=django.utils.timezone.now,
                editable=False,
                verbose_name="Created",
            ),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="datatype",
            field=eav.fields.EavDatatypeField(
                choices=[
                    ("text", "Text"),
                    ("date", "Date"),
                    ("float", "Float"),
                    ("int", "Integer"),
                    ("bool", "True / False"),
                    ("object", "Django Object"),
                    ("enum", "Multiple Choice"),
                ],
                max_length=6,
                verbose_name="Data Type",
            ),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="description",
            field=models.CharField(
                blank=True,
                help_text="Short description",
                max_length=256,
                null=True,
                verbose_name="Description",
            ),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="display_order",
            field=models.PositiveIntegerField(default=1, verbose_name="Display order"),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="enum_group",
            field=models.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                to="eav.EnumGroup",
                verbose_name="Choice Group",
            ),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="modified",
            field=models.DateTimeField(auto_now=True, verbose_name="Modified"),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="name",
            field=models.CharField(
                help_text="User-friendly attribute name",
                max_length=100,
                verbose_name="Name",
            ),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="required",
            field=models.BooleanField(default=False, verbose_name="Required"),
        ),
        migrations.AlterField(
            model_name="attribute",
            name="slug",
            field=eav.fields.EavSlugField(
                help_text="Short unique attribute label",
                unique=True,
                verbose_name="Slug",
            ),
        ),
        migrations.AlterField(
            model_name="value",
            name="created",
            field=models.DateTimeField(
                default=django.utils.timezone.now, verbose_name="Created"
            ),
        ),
        migrations.AlterField(
            model_name="value",
            name="modified",
            field=models.DateTimeField(auto_now=True, verbose_name="Modified"),
        ),
    ]

Filter Form Frontend

Provide a general summary of the issue in the title above.

Detailed Description

I want to use in frontend a filter form from EAV2 Attributes. So in backend all dynamic fields from a model must collect. Then a form is create fields dependend from model type. Then i can include this in my listview template. Then user fills fields and submit it to backend. Backend filter after this eav2 attributes and render result to frontend. It exists a similar package for normal fields with name django-filter that is often use...

Context

I have a django oscar implementation with t-shirts, jeans and now this products have dynamic attributes from eav2 and i want filter this dynamic attributes. Every shop can filter for size, color and further more. But size and color i only need for textiles. When i also have a juwellery then i need another dynamic attributes.

Django-Filter have 65k user and 165 contributers in github so i think many developer want this feature.

Possible Implementation

Implementation as Django-Filter is a good example how it can work also with EAV2...

Validators: validate_enum Always Fails

validate_enum (see validators.py always fails as value is always a string.

Expected Behavior

valildate_enum should not throw a ValidationError when handed a valid pk for EnumValue

Actual Behavior

validate_enum throws a ValidationError when handed a valid pk for EnumValue

Possible Fix

This validator is actually disabled in django-eav (https://github.com/mvpdev/django-eav/blob/master/eav/validators.py#L99-L111)

I've addressed this in my own build like so:

def validate_enum(value):
    from .models import EnumValue

    try:
        instance = EnumValue.objects.get(pk=value)
    except EnumValue.DoesNotExist:
        instance = None

    if not instance:
        raise ValidationError("Must be an EnumValue model object instance")
    if instance and not instance.pk:
        raise ValidationError("EnumValue has not been saved yet")

Steps to Reproduce

  1. Register a model with eav
  2. Create an multiple-choice Attribute (and associated EnumGroup/Value)
  3. Create model instance, choose EnumValue for multi-choice Attribute.

Your Environment

  • Version used:
  • Django version 2.1.4
  • django-eav2==0.11.1 (latest pypi version)
  • Linux 2f525468f45c 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.