Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#33155 closed Bug (fixed)

ModelChoiceIteratorValue is not hashable.

Reported by: Aljaž Košir Owned by: Aljaž Košir
Component: Forms Version: 3.1
Severity: Normal Keywords: ModelChoiceIteratorValue
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Recently I migrated from Django 3.0 to Django 3.1. In my code, I add custom data-* attributes to the select widget options. After the upgrade some of those options broke. Error is {TypeError}unhashable type: 'ModelChoiceIteratorValue'.

Example (this one breaks):

    def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
        context = super().create_option(name, value, label, selected, index, subindex, attrs)
        if not value:
            return context
        if value in self.show_fields: # This is a dict {1: ['first_name', 'last_name']}
            context['attrs']['data-fields'] = json.dumps(self.show_fields[value])

However, working with arrays is not an issue:

    def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
        context = super().create_option(name, value, label, selected, index, subindex, attrs)
        if not value:
            return context
        if value in allowed_values: # This is an array [1, 2]
            ...

Change History (10)

comment:1 by Mariusz Felisiak, 3 years ago

Easy pickings: set
Summary: ModelChoiceIteratorValue is not hashableModelChoiceIteratorValue is not hashable.
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

Thanks for the ticket. Agreed, we could make ModelChoiceIteratorValue hashable by adding:

def __hash__(self):
    return hash(self.value)

For now you can use value.value as documented in the "Backwards incompatible changes in 3.1" section.

Version 0, edited 3 years ago by Mariusz Felisiak (next)

in reply to:  1 comment:2 by Aljaž Košir, 3 years ago

Replying to Mariusz Felisiak:

Thanks for the ticket. Agreed, we could make ModelChoiceIteratorValue hashable by adding:

def __hash__(self):
    return hash(self.value)

For now you can use value.value as documented in the "Backwards incompatible changes in 3.1" section. Would you like to prepare a patch?

Yes, sure.

comment:3 by Aljaž Košir, 3 years ago

Owner: changed from nobody to Aljaž Košir
Status: newassigned

comment:4 by Aljaž Košir, 3 years ago

Has patch: set

comment:5 by Mariusz Felisiak, 3 years ago

Needs tests: set
Patch needs improvement: set

comment:6 by Aljaž Košir, 3 years ago

Patch needs improvement: unset

comment:7 by Aljaž Košir, 3 years ago

Needs tests: unset

comment:8 by Mariusz Felisiak, 3 years ago

Triage Stage: AcceptedReady for checkin
Type: Cleanup/optimizationBug

comment:9 by GitHub <noreply@…>, 3 years ago

Resolution: fixed
Status: assignedclosed

In 7b8beee:

Fixed #33155 -- Made ModelChoiceIteratorValue instances hashable.

comment:10 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

In 0a492760:

[4.0.x] Fixed #33155 -- Made ModelChoiceIteratorValue instances hashable.

Backport of 7b8beeee3d45cafd7bec7ff3ee0e4371e142c36d from main

Note: See TracTickets for help on using tickets.
Back to Top