GithubHelp home page GithubHelp logo

easy-select2-m2m's People

Contributors

asyncee avatar dzerrenner avatar

Watchers

 avatar

easy-select2-m2m's Issues

M2M field value conversion

This is continue of asyncee/django-easy-select2#4 discussion.

First of all, the models.py with improved Parent.__str__ method:

from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=127)

    def __str__(self):
        return self.name

class Parent(models.Model):
    tags = models.ManyToManyField(to='Tag', null=True, blank=True, symmetrical=False)

    def __str__(self):
        return ",".join([unicode(t) for t in self.tags.all()])

Form validation starts with full_clean method. First of all, it validates every field, then clean() method is called. In your case, the ValidationError happened in _clean_fields method, so clean() was never called.

Changes I made:

  1. Set form initial value as a string, instead of list of ids, because Select2 tags expects a string.

  2. Extended a full_clean method that cleans tags using raw form data:

    from django.contrib import admin
    from django import forms
    from easy_select2 import Select2TextInput
    from demoapp.models import Tag, Parent
    
    
    class ParentForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(ParentForm, self).__init__(*args, **kwargs)
    
            def get_choices():
                values = Tag.objects.values_list('name', flat=True).distinct().order_by('name')
                return [x for x in values]
    
            # set select2attrs as stated in https://github.com/asyncee/django-easy-select2/issues/4
            self.fields['tags'].widget = Select2TextInput(
                select2attrs={
                    'tags': get_choices(),
                },
            )
            self.initial = {
                'tags': ', '.join([unicode(t) for t in self.instance.tags.all()]),
            }
    
            # remove the "Use Ctrl for multiple selections" help text
            self.fields['tags'].help_text = ""
    
        def full_clean(self):
            #
            # Tags input should be a list of ids (ints), but for now
            # it is list of single unicode strings, so we should convert
            # it to correct format.
            #
            # Althought this approach is working, it is better to create
            # custom field type that will do appropriate conversions.
            #
            tags_names = self.data.get('tags')
            if tags_names is not None:
                tags_names = tags_names.split(',')
    
                tags_ids = []
                for name in tags_names:
                    try:
                        # It is possible to use get_or_create here.
                        t = Tag.objects.get(name=name)
                    except Tag.DoesNotExist:
                        pass
                    else:
                        tags_ids.append(unicode(t.id))
    
                self.data['tags'] = tags_ids
    
            super(ParentForm, self).full_clean()
    
    
    class ParentAdmin(admin.ModelAdmin):
        form = ParentForm
    
    admin.site.register(Parent, ParentAdmin)
    
    
    admin.site.register(Tag)
    

Hope it helps.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.