-
-
Notifications
You must be signed in to change notification settings - Fork 629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Enum for Select-field #267
Comments
If you think this might be a good idea I could provide a pull request if I find some time over the weekend. |
Ah, I see it's deprecated. Shouldn't then |
@floqqi I would accept a PR adding I'd rather not add HAS_ENUM = False # Check this in OneOf
try:
import enum
except ImportError:
pass
else:
HAS_ENUM = True |
Another option is to add a separate |
I've been using an class Enum(fields.Field):
"""Validates against a given set of enumerated values."""
def __init__(self, enum, *args, **kwargs):
super().__init__(*args, **kwargs)
self.enum = enum
self.validators.insert(0, OneOf([v.value for v in self.enum]))
def _serialize(self, value, attr, obj):
return self.enum(value).value
def _deserialize(self, value):
return self.enum(value)
def _validate(self, value):
if type(value) is self.enum:
super()._validate(value.value)
else:
super()._validate(value) Feel free to grab some of that if it helps. |
What advantages do you see in making it a field and not a validator? |
I think a validator is the way to go. Maybe as a subclass of OneOf - but I've not looked at that particular code so I'm not sure if it'd work gracefully or not. However, with a field it'd be possible to serialize/deserislize, which could very beneficial. |
Was thinking about this today as I have a use case for it (but sadly with only DRF), but I think it might be better as an extension to marshmallow instead of included in core. If I have time this weekend, I'll knock up an example. |
@floqqi I wrote this pretty quick, but I feel it's a decent first draft of what I'd expect this sort of thing to be.. It might fit whatever use case you had in mind. @sloria I'm wondering if there should be like a "Marshmallow Extensions" section of the docs as there's been some nifty things coming out Issues. Not to toot my own horn, but there's been the DRF Compat library and the neat Polyfield as well. |
@justanr Yes, I've been meaning to add an "Ecosystem" page for a while. I think the GitHub wiki would be a good place for this. I'll try to get to this soon. |
@justanr 's |
Is |
@tispratik File an issue on the marshmallow_enum tracker if you're seeing any incompatibility and we'll get it sorted. |
I've finished with own implementation, feel free to use
|
Any reason for this to not be in tree? |
The |
I'm open to it, but we're more focused on stabilizing the API for the final 3.0 release than we are with new features at the moment. We may revisit this after 3.0 is released. |
@deckar01 Supporting the read from and to interface of Enum can be supported without importing the module. If this is of interest to have in marshmallow itself, I'm happy to contribute the code over. We can reconvene this when y'all are comfortable taking it on and figure out a migration path for it. |
I think you should use issubclass() instead of isinstance() |
Is there any foreseeable movement regarding this as 3.0 is now out? |
If you just want the enum symbol names to be validated, you can use the enum's member dict directly. fields.String(validate=OneOf(Color.__members__)) |
It seems that |
You are correct. Looking at the code examples closer, |
Hello together, is there some progress to implement an Enum field into the marshmallow core? Here is a minimal working example to show what I mean: import attr
from enum import Enum
from marshmallow import Schema, fields, post_load
from marshmallow_enum import EnumField
# ---------------------------------------------
# create enum
material_dict = {"wood": "wood", "glas": "glas", "aluminium": "aluminium"}
Material = Enum("Material", material_dict)
# ---------------------------------------------
# create Desk class
@attr.s()
class Desk:
height: float = attr.ib()
material: Material = attr.ib()
# ---------------------------------------------
# WITHOUT EnumField
class DeskSchema(Schema):
height: float = fields.Float()
material: Material = fields.Str()
@post_load
def make_Desk(self, data, **kwargs) -> Desk:
return Desk(**data)
my_desk = Desk(material=Material.glas, height=82.5)
print(my_desk)
schema = DeskSchema()
json_string = schema.dumps(my_desk)
print(json_string)
my_desk_deserialised = schema.loads(json_string)
print(my_desk_deserialised)
# ---------------------------------------------
# WITH EnumField
class DeskSchemaWithEnum(Schema):
height: float = fields.Float()
material: Material = EnumField(Material)
@post_load
def make_Desk(self, data, **kwargs) -> Desk:
return Desk(**data)
schema_with_enum = DeskSchemaWithEnum()
json_string_with_enum = schema_with_enum.dumps(my_desk)
print(json_string_with_enum)
my_desk_deserialised_with_enum = schema_with_enum.loads(json_string_with_enum)
print(my_desk_deserialised_with_enum) The output will be:
So the deserialisation with the |
Just to be sure I understand. Is there any blocker when using marshmallow-enum or are you saying it does the job and you'd like it in the core? (I'd also like this in the core. Just never got the time to look into it since marshmallow 3 is out.) |
I mean the second option, it seems to do the job and I would like it in the core =) |
I have got some use cases where I use a
Enum
in my models.Example:
Now it would be great if I could use the Enum in
marshmallow.fields.Select
:For backwards-compatibility enum34 could be used.
The text was updated successfully, but these errors were encountered: