applegrew / django-select2

This is a Django integration for Select2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

doc example broken

tisdall opened this issue · comments

https://django-select2.readthedocs.io/en/latest/django_select2.html#django_select2.forms.ModelSelect2TagWidget

def value_from_datadict(self, data, files, name):
        values = super().value_from_datadict(self, data, files, name)

I don't think that second self should be there.

... okay, there's multiple issues with that example.. pk, value, queryset are all undefined... That whole example needs rewriting.

@tisdall thanks for investigating this. I would really appreciate your help here. best joe

The best I can come up with is the following:

class MyModelSelect2TagWidget(ModelSelect2TagWidget):
    queryset = MyModel.objects.all()

    def value_from_datadict(self, data, files, name):
        values = super().value_from_datadict(data, files, name)
        qs = self.queryset.filter(**{'pk__in': list(values)})
        pks = set(str(o.pk) for o in qs)
        cleaned_values = []
        for val in values:
            if str(val) not in pks:
                val = self.queryset.create(pk=val).pk
            cleaned_values.append(val)
        return cleaned_values

I think it does what's intended.

Thanks @tisdall how about some tiny tweaks:

class MyModelSelect2TagWidget(ModelSelect2TagWidget):
    queryset = MyModel.objects.all()

    def value_from_datadict(self, data, files, name):
        """Create objects for given non-pimary-key values. Return list of all primary keys."""
        values = set(super().value_from_datadict(data, files, name))
        pks = self.queryset.filter(**{'pk__in': list(values)}).values_list('pk', flat=True)
        pks = set(map(str, pks))
        cleaned_values = list(values)
        for val in values - pks:
            cleaned_values.append(self.queryset.create(title=val).pk)
        return cleaned_values

Yes, that's much better. A method comment string might be good, too. Maybe something like: "return selected MyModel objects and automatically create any new ones as needed"

@codingjoe Yes, but I specifically put in MyModel to try to hammer home the fact that the person using the code example will probably need to modify it to suit their purposes. For example, the method specifically requires that the model has a title attribute. Maybe in the for loop there should also be a # create new user defined MyModel objects to also make it clear they'll likely need to change that part.

@tisdall I created a PR. Lets finish the dicussion over there.