Skip to content
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

enum.EnumField seems not to work in Django 1.10 #39

Closed
georgekpg opened this issue Aug 31, 2016 · 14 comments
Closed

enum.EnumField seems not to work in Django 1.10 #39

georgekpg opened this issue Aug 31, 2016 · 14 comments
Assignees

Comments

@georgekpg
Copy link

In django 1.10 get_deferred_fields routine from django.db.models.base counts all enum.EnumField fields in a model as deferred fields. As a result it passes update_fields in save_base routine and raises "Cannot force an update in save() with no primary key" exception when I attempt to save new model instance.

In django 1.9.9 the same model works okay. I am using django-enumfield==1.3b2 installed with pip

@mandery
Copy link

mandery commented Sep 3, 2016

I have the exactly same issue.

Creating and saving an instance of a model with an EnumField leads to ValueError("Cannot force an update in save() with no primary key.").

@Bartvds
Copy link

Bartvds commented Sep 5, 2016

This is blocking some application upgrades.

Might have something to do with this warning you get using django-enumfield 1.3b2 in django 1.9.x: RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead.

@woodcoder
Copy link

I just found PR #37 which discusses this in more detail...

@servomac
Copy link

servomac commented Oct 8, 2016

I have a similar problem using Django 1.10.2 and django-enumfield 1.2.1:

  File "/usr/local/lib/python3.5/dist-packages/django_enumfield/enum.py", line 6, in <module>
    from django_enumfield.db.fields import EnumField
  File "/usr/local/lib/python3.5/dist-packages/django_enumfield/db/fields.py", line 8, in <module>
    class EnumField(six.with_metaclass(models.SubfieldBase, models.IntegerField)):
AttributeError: module 'django.db.models' has no attribute 'SubfieldBase'

@temclaugh
Copy link

temclaugh commented Oct 24, 2016

This is similar to this issue jpwatts/django-positions#49
A temporary fix is to overwrite the get_deferred_fields method on any model with an EnumField, like this:

def get_deferred_fields(self):
        enum_fields = filter(lambda x: isinstance(x, enum.EnumField), ThisModel._meta.fields)
        enum_field_names = set(funcy.pluck_attr('name', enum_fields))
        deferred_set = super(ThisModel, self).get_deferred_fields()
        return {f for f in deferred_set if f not in enum_field_names}

@Bartvds
Copy link

Bartvds commented Jan 18, 2017

Pinging @lundberg @andreif to ask if this package is dead? What do you use for Django 1.10 at 5monkeys?

@georgekpg
Copy link
Author

Bartvds, I at last ended on using this branch https://github.com/i2biz/django-enumfield/tree/jbzdak/django110. It works ok with django 1.10. Only thing that I lost was validating transitions, but I managed to rewrite it myself as standalone function.

@andreif
Copy link
Contributor

andreif commented Feb 10, 2017

@Bartvds Hi, we just need a project where we could continue to develop the package. Currently I am working with 1.10 one and soon will need to do something about enumfield.

Preliminary plan is to merge enum34 branch and add support for 1.10-1.11.

@sinarezaei
Copy link

@georgekpg Hi, can you please explain how did you manage to rewrite validating transitions, I'm currently having the same issue.

@georgekpg
Copy link
Author

georgekpg commented Mar 29, 2017

@sinarz, my implementation is based upon django-simple-history, it helps me to detect changed fields.

from simple_history.models import HistoricalRecords
from django_enumfield import validators as enum_validators

def validate_enum_transitions(obj,fields):
    try:
        prev = obj.history.most_recent()
    except:
        return
    
    for fname in fields:
        try:
            f = obj._meta.get_field(fname)
        except:
            continue
        if hasattr(f,'enum'):
            enum_validators.validate_valid_transition(f.enum,f.value_from_object(prev),f.value_from_object(obj))

And I can call this in clean method implementation of my model

class Ticket(models.Model):
    status = enum.EnumField(TicketStatus, default=TicketStatus.DRAFT,verbose_name=_('Ticket status'))
    history = HistoricalRecords()

    def clean(self):
        validate_enum_transitions(self,('status',))

@sinarezaei
Copy link

Thanks @georgekpg , nice implementation. I'll give it a try.

@ashkulz
Copy link

ashkulz commented Nov 17, 2017

#43 works for me as a drop-in replacement in Django 1.11, original patch was from @kjagiello

@Swamii
Copy link
Contributor

Swamii commented Sep 13, 2018

Please try version 1.4rc1

@Swamii
Copy link
Contributor

Swamii commented Sep 14, 2018

1.4 has been released. Please reopen if it doesn't work for any reason

@Swamii Swamii closed this as completed Sep 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants