hzdg / django-enumfields Goto Github PK
View Code? Open in Web Editor NEWReal Python Enums for Django
License: Other
Real Python Enums for Django
License: Other
I'm using Django 2.1 and I get errors when I attempt to put a name on an EnumField like:
from django.utils.translation import ugettext_lazy as _
from enumfields import EnumField, Enum
class Grade(Enum):
FRESHMAN = 'fr'
SOPHOMORE = 'sp'
JUNIOR = 'jr'
SENIOR = 'sr'
grade = EnumField(name=_('grade'), enum=Grade, max_length=2)
When I attempt to make migrations the error is TypeError: getattr(): attribute name must be string
I'm getting uppercase enum names in my admin forms. EnumField just uses the enum's names, not their labels: https://github.com/hzdg/django-enumfields/blob/master/enumfields/fields.py#L17, but the readme says that by using enumfields.Enum I should get titlecased names.
/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/enumfields/fields.py:92: RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead.
class EnumField(EnumFieldMixin, models.CharField):/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/enumfields/fields.py:92: RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead.
class EnumField(EnumFieldMixin, models.CharField):
File "/home/david/anaconda3/lib/python3.4/site-packages/enumfields/fields.py", line 20, in init
options["choices"] = [(i, getattr(i, 'label', i.name)) for i in self.enum] # choices for the TypedChoiceField
TypeError: 'type' object is not iterable
I've created an enum with an __init__
method, which should be fine. But it looks like django is confused when it tries to store that in the database.
My Enum/class is as below:
class SkillAbility(models.Model):
class Skills(Enum):
ACADEMICS = ('Academics', 'Mental')
COMPUTER = ('Computer', 'Mental')
def __init__(self, label, skill_type):
self.label = label
self.skill_type = skill_type
@property
def type(self):
return self.skill_type
skill = EnumField(Skills)
And this is the error code from Django:
InterfaceError at /admin/characters/skillability/add/
Error binding parameter 0 - probably unsupported type.
This is the method:
def execute(self, query, params=None):
if params is None:
return Database.Cursor.execute(self, query)
query = self.convert_query(query)
return Database.Cursor.execute(self, query, params)
And these are the values of the local variables:
params: [('Academics', 'Mental')]
query: 'INSERT INTO "characters_skillability" ("skill") VALUES (?)'
self: <django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x0000000004D5A1F8>
The whole query would be: 'INSERT INTO "characters_skillability" ("skill") VALUES (('Academics', 'Mental'))'
which is not valid.
It should be: 'INSERT INTO "characters_skillability" ("skill") VALUES (?,?)'
and unpack the tuple.
Is this possible?
Hello
Is that possible to restrict choices of enum class in serializer ?
This is my enum class:
class TransferType(Enum):
Paypal = "PP"
WesternUnion = "WU"
Wallet = "WT"
class Labels:
Paypal = _('Paypal')
WesternUnion = _('Western Union')
Wallet = _('Wallet')
My serializer:
class TransferSerializer(EnumSupportSerializerMixin, serializers.ModelSerializer):
wallet = serializers.SerializerMethodField(source='get_wallet')
transfer_type = EnumField(enum=[TransferType.Paypal, TransferType.WesternUnion ])
.......
I got this error when I post data:
isinstance() arg 2 must be a type or tuple of types
Exception Value: | isinstance() arg 2 must be a type or tuple of types
Exception Location: C:\Users\mehdi\PycharmProjects\venv\lib\site-packages\enumfields\drf\fields.py, line 35, in to_internal_value
Thank you
If I setup my model using the following format:
from enumfields import (
EnumField,
Enum,
EnumIntegerField
)
class Profile(models.Model):
class Employment(Enum):
UNSPECIFIED = 1
FULL_TIME = 2
LOOKING_FOR_WORK = 3
NOT_LOOKING_FOR_WORK = 4
RETIRED = 5
STUDENT = 6
HOMEMAKER = 7
class Labels:
FULL_TIME = _('Employed full time')
LOOKING_FOR_WORK = _('Not employed but looking for work')
NOT_LOOKING_FOR_WORK = _('Not employed and not looking for work')
RETIRED = _('Retired')
STUDENT = _('Student')
HOMEMAKER = _('Homemaker')
UNSPECIFIED = _('I prefer not to say')
employment = EnumIntegerField(Employment, max_length=1, null=True, blank=True)
And then in the template
{{ form.employment }}
After selecting the drop-down, 'Not employed but looking for work' I will receive a validation error of '3 is not a valid choice.'.
I've tried various number of tweaks but all result in similar behaviour (including passing choices= to the model field).
Looks like some tweaks are going to be needed to work in Python 3.11?
https://docs.python.org/3/whatsnew/3.11.html#enum
File "/python3.11/site-packages/enumfields/enums.py", line 17, in new
attrs._member_names.remove('Labels')
^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'remove'
After updated to django-enumfields==2.1.0
I am getting the following error in a unit test that tests generation of OpenAPI schema using drf-yasg2
.
The enum
being used is:
from django.contrib.postgres.fields import ArrayField
@unique
class Tag(Enum):
Upper = "upper"
Lower = "lower"
class MyModel(models.Model):
tags = ArrayField(EnumField(Tag), blank=True, null=True)
...
Relevant verisions:
Django==3.1.6
drf-yasg==1.20.0
django-enumfields==2.1.0
Traceback (most recent call last):
File "/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/venv/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/venv/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/venv/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/venv/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/venv/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/venv/lib/python3.9/site-packages/drf_yasg/views.py", line 94, in get
schema = generator.get_schema(request, self.public)
File "/venv/lib/python3.9/site-packages/drf_yasg/generators.py", line 246, in get_schema
paths, prefix = self.get_paths(endpoints, components, request, public)
File "/venv/lib/python3.9/site-packages/drf_yasg/generators.py", line 404, in get_paths
operation = self.get_operation(view, path, prefix, method, components, request)
File "/venv/lib/python3.9/site-packages/drf_yasg/generators.py", line 446, in get_operation
operation = view_inspector.get_operation(operation_keys)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py", line 45, in get_operation
responses = self.get_responses()
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py", line 180, in get_responses
response_serializers = self.get_response_serializers()
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py", line 235, in get_response_serializers
responses = self.get_default_responses()
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py", line 211, in get_default_responses
default_schema = self.serializer_to_schema(default_schema) or ''
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 437, in serializer_to_schema
return self.probe_inspectors(
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 110, in probe_inspectors
result = method(obj, **kwargs)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py", line 33, in get_schema
return self.probe_field_inspectors(serializer, openapi.Schema, self.use_definitions)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 228, in probe_field_inspectors
return self.probe_inspectors(
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 110, in probe_inspectors
result = method(obj, **kwargs)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py", line 124, in field_to_swagger_object
actual_schema = definitions.setdefault(ref_name, make_schema_definition)
File "/venv/lib/python3.9/site-packages/drf_yasg/openapi.py", line 688, in setdefault
ret = maker()
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py", line 100, in make_schema_definition
child_schema = self.probe_field_inspectors(
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 228, in probe_field_inspectors
return self.probe_inspectors(
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 110, in probe_inspectors
result = method(obj, **kwargs)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py", line 77, in field_to_swagger_object
child_schema = self.probe_field_inspectors(field.child, ChildSwaggerType, use_references)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 228, in probe_field_inspectors
return self.probe_inspectors(
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py", line 110, in probe_inspectors
result = method(obj, **kwargs)
File "/venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py", line 640, in field_to_swagger_object
choice = field_value_to_representation(field, choice)
File "/venv/lib/python3.9/site-packages/drf_yasg/utils.py", line 461, in field_value_to_representation
value = field.to_representation(value)
File "/venv/lib/python3.9/site-packages/enumfields/drf/fields.py", line 22, in to_representation
assert isinstance(instance, self.enum), instance
AssertionError: upper
rest_api/tests/test_views/test_api/test_swagger.py:8 (test_swagger)
client = <rest_framework.test.APIClient object at 0x11b307580>
django_user_model = <class 'django.contrib.auth.models.User'>
def test_swagger(client: APIClient, django_user_model: Model) -> None:
"""Ensure the OpenAPI specification is generated without error."""
create_and_login(client, django_user_model)
> resp = client.get(f"{swagger_json_url}")
test_swagger.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../venv/lib/python3.9/site-packages/rest_framework/test.py:288: in get
response = super().get(path, data=data, **extra)
../../../../venv/lib/python3.9/site-packages/rest_framework/test.py:205: in get
return self.generic('GET', path, **r)
../../../../venv/lib/python3.9/site-packages/rest_framework/test.py:233: in generic
return super().generic(
../../../../venv/lib/python3.9/site-packages/django/test/client.py:470: in generic
return self.request(**r)
../../../../venv/lib/python3.9/site-packages/rest_framework/test.py:285: in request
return super().request(**kwargs)
../../../../venv/lib/python3.9/site-packages/rest_framework/test.py:237: in request
request = super().request(**kwargs)
../../../../venv/lib/python3.9/site-packages/django/test/client.py:716: in request
self.check_exception(response)
../../../../venv/lib/python3.9/site-packages/django/test/client.py:577: in check_exception
raise exc_value
../../../../venv/lib/python3.9/site-packages/django/core/handlers/exception.py:47: in inner
response = get_response(request)
../../../../venv/lib/python3.9/site-packages/django/core/handlers/base.py:181: in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
../../../../venv/lib/python3.9/site-packages/django/views/decorators/csrf.py:54: in wrapped_view
return view_func(*args, **kwargs)
../../../../venv/lib/python3.9/site-packages/django/views/generic/base.py:70: in view
return self.dispatch(request, *args, **kwargs)
../../../../venv/lib/python3.9/site-packages/rest_framework/views.py:509: in dispatch
response = self.handle_exception(exc)
../../../../venv/lib/python3.9/site-packages/rest_framework/views.py:469: in handle_exception
self.raise_uncaught_exception(exc)
../../../../venv/lib/python3.9/site-packages/rest_framework/views.py:480: in raise_uncaught_exception
raise exc
../../../../venv/lib/python3.9/site-packages/rest_framework/views.py:506: in dispatch
response = handler(request, *args, **kwargs)
../../../../venv/lib/python3.9/site-packages/drf_yasg/views.py:94: in get
schema = generator.get_schema(request, self.public)
../../../../venv/lib/python3.9/site-packages/drf_yasg/generators.py:246: in get_schema
paths, prefix = self.get_paths(endpoints, components, request, public)
../../../../venv/lib/python3.9/site-packages/drf_yasg/generators.py:404: in get_paths
operation = self.get_operation(view, path, prefix, method, components, request)
../../../../venv/lib/python3.9/site-packages/drf_yasg/generators.py:446: in get_operation
operation = view_inspector.get_operation(operation_keys)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py:45: in get_operation
responses = self.get_responses()
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py:180: in get_responses
response_serializers = self.get_response_serializers()
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py:235: in get_response_serializers
responses = self.get_default_responses()
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/view.py:211: in get_default_responses
default_schema = self.serializer_to_schema(default_schema) or ''
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:437: in serializer_to_schema
return self.probe_inspectors(
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:110: in probe_inspectors
result = method(obj, **kwargs)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py:33: in get_schema
return self.probe_field_inspectors(serializer, openapi.Schema, self.use_definitions)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:228: in probe_field_inspectors
return self.probe_inspectors(
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:110: in probe_inspectors
result = method(obj, **kwargs)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py:124: in field_to_swagger_object
actual_schema = definitions.setdefault(ref_name, make_schema_definition)
../../../../venv/lib/python3.9/site-packages/drf_yasg/openapi.py:688: in setdefault
ret = maker()
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py:100: in make_schema_definition
child_schema = self.probe_field_inspectors(
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:228: in probe_field_inspectors
return self.probe_inspectors(
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:110: in probe_inspectors
result = method(obj, **kwargs)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py:77: in field_to_swagger_object
child_schema = self.probe_field_inspectors(field.child, ChildSwaggerType, use_references)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:228: in probe_field_inspectors
return self.probe_inspectors(
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/base.py:110: in probe_inspectors
result = method(obj, **kwargs)
../../../../venv/lib/python3.9/site-packages/drf_yasg/inspectors/field.py:640: in field_to_swagger_object
choice = field_value_to_representation(field, choice)
../../../../venv/lib/python3.9/site-packages/drf_yasg/utils.py:461: in field_value_to_representation
value = field.to_representation(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = EnumField(choices=[(<Tag.Upper: 'upper'>, 'Upper'), (<Tag.Lower: 'lower'>, 'Lower')], enum=<enum 'Tag'>, label='Tags')
instance = 'upper'
def to_representation(self, instance):
> assert isinstance(instance, self.enum), instance
E AssertionError: upper
../../../../venv/lib/python3.9/site-packages/enumfields/drf/fields.py:22: AssertionError
Stepping through in the debugger, it looks like to_representation()
is being passed a str
instance
which is tripping this assertion.
The unit test is roughly:
def test_swagger(client: APIClient) -> None:
"""Ensure the OpenAPI specification is generated without error."""
resp = client.get("/rest/api/swagger.json")
assert resp.status_code == HTTP_200_OK
This is related to #120. The proposed solution there doesn't work for us, though. The selectable values should be returned in the OPTIONS
call for the frontend to only show them.
In our usecase it shouldn't be possible to select all values of an Enum on the model, also for the database model. An idea would be to add this as an additional parameter to the model field, e.g.:
enum_field_with_limited_choices = EnumField(
EnumWithManyChoices,
max_length=100,
selectable_choices=[EnumWithManyChoices.Choice1, EnumWithManyChoices.Choice2]
)
I guess this would be trivial to implement. If you agree it's useful, I can make a proposal.
Hi,
Great package, I just learnt about it from a friend that's using it. Django 3.0 includes enumeration types which seem to duplicate much of the functionality here.
Perhaps a link in the documentation would be nice, to guide users finding this library?
Thanks,
Adam
Would be nice to add an option to serialize enum name instead of value.
I use such objects:
class FrequencyChoices(Enum):
monthly = relativedelta.relativedelta(months=1)
quarterly = relativedelta.relativedelta(months=3)
The values are not serializable so I need to serialize the name instead. Maybe the best would just be to rename the option ints_as_names and do not constraint its usage to enums storing int values. I can think about other applications where it could be preferable to serialize the name, even if the value is also serializable:
class CurrencyChoices(Enum):
euro = "€"
us_dollar = "$"
AttributeError at /admin/someapp/someclass/
'unicode' object has no attribute 'value'
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/someapp/someclass/?continent2__exact=Continent.AFRICA
Django Version: 1.8.4
Exception Type: AttributeError
Exception Value:
'unicode' object has no attribute 'value'
Exception Location: /Users/jessamyn/.virtualenvs/mentor/lib/python2.7/site-packages/enumfields/fields.py in get_prep_value, line 35
It would be very nice if actual 'enum' type would be used for databases that support them.
(enum.Enum):
File "/home/asif/.pyenv/versions/3.8.2/lib/python3.8/enum.py", line 212, in new
enum_member = new(enum_class, *args)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'dict'
Right now we need to use EnumFieldListFilter like this:
from enumfields.admin import EnumFieldListFilter
class MyModelAdmin(admin.ModelAdmin):
list_filter = [('color', EnumFieldListFilter)]
It's easy to forget it (see #75 ).
But there is a better way. By using django's FieldListFilter.register
we can "attach" the filter to the EnumField:
from django.contrib.admin.filters import FieldListFilter
from .fields import EnumFieldMixin
class EnumFieldListFilter(ChoicesFieldListFilter):
....
FieldListFilter.register(lambda f: isinstance(f, EnumFieldMixin), EnumFieldListFilter)
This should work with both EnumField and EnumIntegerField fields. The EnumFieldListFilter section in the README won't be needed anymore.
This should work for django > 1.4. For older versions there is a workaround.
Would you be interested in a pull request? These days I try to ask beforehand.
It seems default django-enumfields form field rendering is incompatible with django-filters
class Color(Enum):
RED = 'r'
GREEN = 'g'
BLUE = 'b'
class MyModel(models.Model):
name1 = models.CharField(max_length=250)
name2 = models.CharField(max_length=250)
color = EnumField(Color, max_length=1)
class MyModelFilterSet(FilterSet):
class Meta:
model = MyModel
fields = [ 'color']
This code cause to render following filter
<select name="color" id="id_color">
<option value="" selected="">---------</option>
<option value="Color.RED">RED</option>
<option value="Color.GREEN">GREEN</option>
<option value="Color.BLUE">BLUE</option>
</select>
Wich leads to
'Color.RED' is not a valid Color
Hi all,
I think it will be nice when the max_length will be calculated automatically by default.
What do you think?
Including the tests makes it easier for distro packagers to test the built package.
Django dropped Python2 support a while ago already. In Django 3.0 python_2_unicode_compatibility
and django.utils.six
have been deleted. Hence starting an application that uses django-enumfields
fails.
I tried to add enumfields to my existing Django 1.7 project.
from enumfields import Enum class InviteStatus(Enum): REQUESTED = 0 SENT = 1 VIEWED = 2 APPROVED = 3 EnumIntegerField(values.InviteStatus, max_length=1, default=values.InviteStatus.REQUESTED)
When running makemigrations, I receive a traceback. I think its due to the fact Django doesn't know how to serialize the enums:
Traceback (most recent call last): File "manage.py", line 10, in execute_from_command_line(sys.argv) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line utility.execute() File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv self.execute(*args, **options.__dict__) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute output = self.handle(*args, **options) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 124, in handle self.write_migration_files(changes) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 152, in write_migration_files migration_string = writer.as_string() File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/db/migrations/writer.py", line 129, in as_string operation_string, operation_imports = OperationWriter(operation).serialize() File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/db/migrations/writer.py", line 86, in serialize arg_string, arg_imports = MigrationWriter.serialize(arg_value) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/db/migrations/writer.py", line 310, in serialize return cls.serialize_deconstructed(path, args, kwargs) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/db/migrations/writer.py", line 221, in serialize_deconstructed arg_string, arg_imports = cls.serialize(arg) File "/Users/bryanmarty/.env/groupguys/lib/python2.7/site-packages/django/db/migrations/writer.py", line 380, in serialize raise ValueError("Cannot serialize: %r\nThere are some values Django cannot serialize into migration files.\nFor more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing" % value) ValueError: Cannot serialize: There are some values Django cannot serialize into migration files. For more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing
I am receiving an error when I try to save a model object when I set an enum:
Error binding parameter 3 - probably unsupported type.
My dev DB is sqlite.
model simply contains an my_enum_field = EnumIntegerField(enum=MyEnumType)
view is simply trying to set the value of this enum field:
my_model.my_enum_field = MyEnumType.MYVALUE
my_model.save()
Any idea why this might be happening?
The completely strange thing is, I am using django rest framework and this isn't the first time I've used EnumIntegerField, in that other case, the value is being saved from the serializer and never directly from the view.
Edit: After more research it seems that, the value is trying to be saved to the database as a tuple. Also when an integer is manually saved into the database, I am getting validation errors when trying to read the value (e.g. 0 is not a valid enum value errors)
README describes that enums should be declared inside the class they are used in.
class MyModel(models.Model):
class Color(Enum):
RED = 'r'
GREEN = 'g'
BLUE = 'b'
color = EnumField(Color, max_length=1)
This causes problems with Django because migrations cannot import the missing Color
class.
I think the proper example given should be something in the lines of:
class Color(Enum):
RED = 'r'
GREEN = 'g'
BLUE = 'b'
class MyModel(models.Model):
color = EnumField(Color, max_length=1)
…or remove it from the tox config.
https://travis-ci.org/hzdg/django-enumfields/builds/71827205
I would like to report a weird action when I try to use filtering with DRF 3.4, django-filter 0.13 and django-enumfields 0.8.1, drf-enum-field 0.9.1
I made a request with url http://url/api/MyModels?test_type=a and the response said "['Select a valid choice. A is not one of the available choices.']".
It turns out that ChoiceField.valid_value() returns False because k, v in choices are both label instead of name and value so it keeps failing.
They should be name and value and tries to compare with query param which is 'a'.
This is my sample code
class TestType(Enum)
A = 'a'
class Labels:
A = 'a-label'
class MyModel(Model):
test_type = EnumField(TestType, max_length=MAX_TEST_TYPE_LENGTH)
I think EnumField should override valid_value() and makes sure overridden method called instead of ChoiceField.
When upgrading from 0.7.4 to 0.8.0 I found that the behaviour of enum fields has changed if you are initialising them via their String value rather than by their enum type.
This behaviour was a side effect of the changes to remove the deprecated SubfieldBase (8260050).
I have had a short attempt at fixing this but haven't managed to find a way. (I'm thinking from my reading of the SubfieldBase related material that it might have something to do with replacing the __new__
method).
I have written a test to demonstrate the issue:
# -- encoding: UTF-8 --
import pytest
from .models import MyModel
try:
from .enums import Color # Use the new location of Color enum
except ImportError:
Color = MyModel.Color # Attempt the 0.7.4 location of color enum
@pytest.mark.django_db
def test_fields_value_is_enum_when_unsaved():
obj = MyModel(color='r')
assert Color.RED == obj.color
@pytest.mark.django_db
def test_fields_value_is_enum_when_saved():
obj = MyModel(color='r')
obj.save()
assert Color.RED == obj.color
@pytest.mark.django_db
def test_fields_value_is_enum_when_created():
obj = MyModel.objects.create(color='r')
assert Color.RED == obj.color
@pytest.mark.django_db
def test_fields_value_is_enum_when_retrieved():
MyModel.objects.create(color='r')
obj = MyModel.objects.first()
assert Color.RED == obj.color
To see the failure copy this test into a file in the tests
directory and run
> python manage.py test
To see it pass, checkout 0.7.4 and run it again!
Python 3.5 and Django 1.9 are both out now, would be great if they were added to the tox.ini
configuration and officially supported.
Currently, we're only testing up to 1.6.
Hi!
I did several pull requests two months ago, but they aren't approved or rejected yet.
Currently, I have several new improvements ideas. Should I make a pull request or it will never be approved?
I'm using ModelSerializer with enumfield. Here is my code:
class ProfileSerializer(EnumSupportSerializerMixin, serializers.ModelSerializer):
default_shipping_address = AddressSerializer(required=False, allow_null=True)
#gender = EnumField(Gender)
class Meta:
model = User
fields = ('id', 'profile_picture', 'email', 'first_name', 'last_name', 'phone', 'gender',
'default_shipping_address',
'is_email_confirmed', 'date_joined', 'last_login',)
..........
Post request and get request work perfectly with this code but when calling Options request, I got this error:
I tried with EnumSupportSerializerMixin and EnumField(Gender) from enumfields.drf.fields.When I remove gender field from serializer, Options work well:
Thank in advance for the answer.
Hi there,
I propose to change this
kwargs['choices'] = tuple((e.value, getattr(e, 'label', e.name)) for e in self.enum)
to this
kwargs['choices'] = tuple((e.value, getattr(e, 'label', e.name)) for e in kwargs.get('choices', self.enum))
to have posibility accept only part of the enum.
Has anyone tried?
If it works can we add to tox? If not, what can we fix?
Hi,
could you please add support for Django >= 1.7. I get the following error:
TypeError: Couldn't reconstruct field gender on webapp.MxUser: __init__() missing 1 required positional argument: 'enum'
.. when running:
$ python manage.py makemigrations
Thank you!
If you navigate here: https://travis-ci.org/github/hzdg/django-enumfields
Since June 15th, 2021, the building on travis-ci.org is ceased. Please use travis-ci.com from now on.
This project will need to migrate to either travis-ci.com or GitHub Actions/Circle CI/etc.
Travis CI (.com) is no longer free for FOSS projects
I would personally recommend GitHub Actions. An example of how to set up GitHub Actions with tox:
Telling South about the "enum" attribute isn't enough since south tries to call the value to clean it in modelsinspector.clean_value()
, causing an error.
The template form is being incorrectly rendered when Labels: nested class has been defined.
{{ form.myField }}
In the drop down selection, it will include all the options as expected, but also a 'Labels' option which should not be present.
I am trying to create an API using django-rest-framework, on a model object which has fields of type EnumIntegerField. When I make an API call, I get an error that the Enum is not JSON serializable.
Traceback:
File "/Users/jessamyn/.virtualenvs/eggtimer/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
137. response = response.render()
File "/Users/jessamyn/.virtualenvs/eggtimer/lib/python3.4/site-packages/django/template/response.py" in render
103. self.content = self.rendered_content
File "/Users/jessamyn/.virtualenvs/eggtimer/lib/python3.4/site-packages/rest_framework/response.py" in rendered_content
59. ret = renderer.render(self.data, media_type, context)
File "/Users/jessamyn/.virtualenvs/eggtimer/lib/python3.4/site-packages/rest_framework/renderers.py" in render
98. separators=separators
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/__init__.py" in dumps
237. **kw).encode(obj)
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/encoder.py" in encode
192. chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/encoder.py" in iterencode
250. return _iterencode(o, 0)
File "/Users/jessamyn/.virtualenvs/eggtimer/lib/python3.4/site-packages/rest_framework/utils/encoders.py" in default
63. return super(JSONEncoder, self).default(obj)
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/encoder.py" in default
173. raise TypeError(repr(o) + " is not JSON serializable")
Exception Type: TypeError at /api/v2/periods/
Exception Value: <FlowLevel.MEDIUM: 2> is not JSON serializable
Django provides Form fields that can be used directly in Form
objects.
Does django-enumfields
provide an EnumField
that can be used directly in a form like:
from django import forms
import enumfields
class MyForm(forms.Form):
my_enum = enumfields. # ... ?
I can get it to work if I put an enumfields.EnumIntegerField
into a Model
and then use a ModelForm
, but if I just want to create a Form
without a Model
I couldn't figure out how to do this.
I'm happy to submit a PR with an example if someone could teach me how to do this. :)
New Django breaks this package. Particularly, when we serialize a query to JSON.
Field._get_val_from_obj() will be removed in favor of Field.value_from_object().
https://docs.djangoproject.com/en/dev/internals/deprecation/#deprecation-removed-in-2-0
It's being used here in line 81
value = self._get_val_from_obj(obj)
https://github.com/hzdg/django-enumfields/blob/master/enumfields/fields.py
The url that django generates for filers (field__exact=x
) ends up using str(some_enum)
instead of some_enum.value
for x
.
This is can be tested by adding a field_x
(which is an enum field) to the filters = ('field_x',)
of a registered model admin.
@akx Could a new release be pushed to PyPI with some of the latest PR fixes that have been merged?
Last release was about a year ago: https://pypi.org/project/django-enumfields/2.0.0/
Thanks.
Upon upgrading to Django 2.1.1, I'm getting a lot of this:
/app/.heroku/python/lib/python3.6/site-packages/django/db/models/sql/compiler.py:995: RemovedInDjango30Warning:
Remove the context parameter from EnumField.from_db_value(). Support for it will be removed in Django 3.0.
I'm guessing this is due to enumfields/fields.py:72:
def from_db_value(self, value, expression, connection, context):
return self.to_python(value)
Is there a way we can drop the last parameter, dependent on the version of Django being used, or possibly just convert this to *args
?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.