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

RemovedInDjango110Warning: SubfieldBase has been deprecated #39

Closed
autogestion opened this issue Dec 6, 2015 · 16 comments
Closed

RemovedInDjango110Warning: SubfieldBase has been deprecated #39

autogestion opened this issue Dec 6, 2015 · 16 comments

Comments

@autogestion
Copy link

Django 1.9 throws such warning:

.../lib/python3.4/site-packages/django/db/models/fields/subclassing.py:22: RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead.

SubfieldBase is used here

MultiSelectField = add_metaclass(models.SubfieldBase)(MultiSelectField)

@morocarlo
Copy link

anyone know who to fix it?

@tammyalexandra
Copy link

+1

1 similar comment
@im-n1
Copy link

im-n1 commented Jan 22, 2016

+1

@jenlu
Copy link

jenlu commented Jan 23, 2016

Hi, here is an attempt at a fix that in some ways reverts to using strings that perhaps can inspire someone to add this to the code. Seems like just keeping the to_python and from_db_value to return lists will mess up how values() and values_lists() works on query sets:

(1) delete the subfieldbase referens, as not needed anymore
(2) ensure to_python() returns a list (but accepts strings, lists, None)
(3) ensure from_db_value() returns a string
(4) change in contribute_to_class() so the iteration accepts a string and splits this into a list

def contribute_to_class(self, cls, name):

    super(MultiSelectField, self).contribute_to_class(cls, name)
    if self.choices:
        def get_list(obj):
            fieldname = name
            choicedict = dict(self.choices)
            display = []

            if getattr(obj, fieldname):
                # for value in getattr(obj, fieldname):
                for value in getattr(obj, fieldname).split(','):
                    item_display = choicedict.get(value, None)
                    if item_display is None:
                        try:
                            item_display = choicedict.get(int(value), value)
                        except (ValueError, TypeError):
                            item_display = value
                    display.append(string_type(item_display))
            return display

        def get_display(obj):
            return ", ".join(get_list(obj))

        setattr(cls, 'get_%s_list' % self.name, get_list)
        setattr(cls, 'get_%s_display' % self.name, get_display)

(5) in MultiSelectFormField add/override prepare_value() so it returns a list

class MultiSelectFormField(forms.MultipleChoiceField):

def prepare_value(self, value):
    '''
        Override prepare_value to convert string to list, so it can be used
    '''
    if value==None or value=='':
        return []
    elif isinstance(value, list):
        return value
    elif isinstance(value, basestring):
        return value.split(",") 

@drernie
Copy link

drernie commented Feb 27, 2016

+1

@drernie
Copy link

drernie commented Mar 25, 2016

Appears to be blocked by #40

@autogestion
Copy link
Author

Looks like adding

def from_db_value(self, value, expression, connection, context):
    return self.to_python(value)

and removing

MultiSelectField = add_metaclass(models.SubfieldBase)(MultiSelectField)

fix the problem

#40 .values_list() works fine

Django==1.9.5

@im-n1
Copy link

im-n1 commented Apr 13, 2016

Great work there!

Can someone please update the repo and release new version?

Thank in advance.

@platzhersh
Copy link

what's the status here? Would offer help to close this matter

@im-n1
Copy link

im-n1 commented Jul 22, 2016

I guess the only solution is fork the project, name it "django-multiselectfield-updated" and release it on PyPy.
The origin author is probably dead :)

@Sergiy-Solomka
Copy link

Did what autogestion commented, and look like its work good... I am sure will be grate if somebody can update the project, thanks..

@lorinkoz
Copy link

@autogestion, I would recommend a couple of changes in your code:

def from_db_value(self, value, expression, connection, context):
    if value is None:
        return value
    return self.to_python(value)

and instead of removing the metaclass, add a Django version check for backwards compatibility (the deprecation was introduced in Django 1.8):

if django.VERSION[0] = 1 and django.VERSION[1] < 8:
    MultiSelectField = add_metaclass(models.SubfieldBase)(MultiSelectField)

@blag
Copy link
Collaborator

blag commented Sep 22, 2016

I'm the new maintainer. I'll try to get to this soon, right now I'm expanding the tests to tests with Django 1.8+. If I forget to fix this, feel free to ping me.

@blag
Copy link
Collaborator

blag commented Sep 22, 2016

@platzhersh: If you have the time and inclination to help, get this into a mergeable and test-passable PR for me and I'll merge it in.

@blag
Copy link
Collaborator

blag commented Sep 22, 2016

Thanks to @lorinkoz's PR #47, this is now in master. I'll try to cut a PyPI release today or tomorrow.

Closing.

@blag blag closed this as completed Sep 22, 2016
@blag
Copy link
Collaborator

blag commented Sep 23, 2016

Version 0.1.4 has just been pushed to PyPI, and includes this fix.

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