crucialfelix / django-ajax-selects

jQuery UI-powered auto-complete fields for ForeignKey, ManyToMany and text fields
Other
822 stars 249 forks source link

Autocomplete using `inlineformset_factory` #287

Open eudaldt opened 2 years ago

eudaldt commented 2 years ago

Is it possible to use the autocomplete using inlineformset_factory? In my case the autocomplete doesn't work...

This is my forms.py:


class FormulariMostra(ModelForm):
    class Meta:
        model = Sample
        fields = ("name", "sample_id_sex",)

class FormulariPoolIndexList(ModelForm):
    class Meta:
        model = SamplePoolIndexCand
        fields = ("pool_id", "index_id", "gene_cand_list_id",)
    pool_id = AutoCompleteSelectField('pool_tag')    
    index_id = AutoCompleteSelectField('index_tag')
    gene_cand_list_id = AutoCompleteSelectField('list_tag')

PoolIndexListFormset = inlineformset_factory(Sample, SamplePoolIndexCand, 
form=FormulariPoolIndexList, extra=2,)

My models:


class Index(models.Model):
    id_index = models.AutoField(primary_key=True)
    index_name = models.CharField(max_length=30)
    index_id_index_type = models.ForeignKey(IndexType, on_delete=models.CASCADE, db_column='id_index_type', verbose_name="Tipus d'índex")
    index_id_index_provider = models.ForeignKey(IndexProvider, on_delete=models.CASCADE, db_column='id_index_provider', verbose_name="Proveïdor d'índex")
    miseq = models.CharField(max_length=9)
    nextseq = models.CharField(max_length=9)

    class Meta:
        db_table = 'index'
        unique_together = (("index_name", "index_id_index_type", "index_id_index_provider", "miseq", "nextseq"),)

    def __str__(self):
        return self.index_name

class GeneCandList(models.Model):
    id_gene_cand_list = models.AutoField(primary_key=True)
    name = models.CharField(unique=True, max_length=150, verbose_name="Llista de gens candidats")

    class Meta:
        db_table = 'gene_cand_list'

    def __str__(self):
        return self.name

class Pool(models.Model):
    id_pool = models.AutoField(primary_key=True)
    name = models.CharField(unique=True, max_length=50, verbose_name="Pool")
    hibridation = models.BooleanField(verbose_name="Hibridació OK?")
    samples = models.ManyToManyField('Sample', through='SamplePoolIndexCand', blank=True, verbose_name="Mostres"

    class Meta:
        ordering = ['-id_pool']
        db_table = 'pool'

    def __str__(self):
        return self.name

class Sample(models.Model):
    id_sample = models.AutoField(primary_key=True)
    name = models.CharField(unique=True, max_length=20)
    sample_id_sex = models.ForeignKey(Sex, on_delete=models.CASCADE, db_column='id_sex', verbose_name='Sexe')
    indexes = models.ManyToManyField(Index, through='SamplePoolIndexCand', through_fields=('sample_id', 'index_id'), blank=True, verbose_name="Índexs")
    pools = models.ManyToManyField(Pool, through='SamplePoolIndexCand', through_fields=('sample_id', 'pool_id'), blank=True, verbose_name="Pools")
    gene_cand_lists = models.ManyToManyField(GeneCandList, through='SamplePoolIndexCand', through_fields=('sample_id', 'gene_cand_list_id'), blank=True, verbose_name="Llista de gens candidats")

    class Meta:
        db_table = 'sample'

    def __str__(self):
        return self.name

class SamplePoolIndexCand(models.Model):
    sample_id = models.ForeignKey(Sample, null=True, blank=True, on_delete=models.CASCADE, db_column='id_sample', verbose_name='Mostra')
    pool_id = models.ForeignKey(Pool, null=True, blank=True, on_delete=models.CASCADE, db_column='id_pool', verbose_name='Pool')
    index_id = models.ForeignKey(Index, null=True, blank=True, on_delete=models.CASCADE, db_column='id_index', verbose_name='Índex')
    gene_cand_list_id = models.ForeignKey(GeneCandList, null=True, blank=True, on_delete=models.CASCADE, db_column='id_gene_cand_list', verbose_name='Llista de gens candidats')

    class Meta:
        unique_together = (("sample_id", "pool_id", "index_id", "gene_cand_list_id"),)
        db_table = 'sample_pool_index_cand'

My views.py:


class SampleForm(CreateView):
    form_class = FormulariMostra
    template_name = 'sample/formulari_mostra.html'
    def get_context_data(self, **kwargs):
        context = super(SampleForm, self).get_context_data(**kwargs)
        context['pool_index_list_formset'] = PoolIndexListFormset()
        return context
    def post(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        pool_index_list_formset = PoolIndexListFormset(self.request.POST)
        if form.is_valid() and pool_index_list_formset.is_valid():
            return self.form_valid(form, pool_index_list_formset)
        else:
            return self.form_invalid(form, pool_index_list_formset)
    def form_valid(self, form, pool_index_list_formset):
        self.object = form.save(commit=False)
        self.object.save()

        pool_index_list = pool_index_list_formset.save(commit=False)
        for meta in pool_index_list:
            meta.sample_id = self.object
            meta.save()
            return redirect("/sample_form/")
    def form_invalid(self, form, pool_index_list_formset):
        return self.render_to_response(
            self.get_context_data(form=form,
                                  pool_index_list_formset=pool_index_list_formset
                                  )
        )

My lookups:


**@register('pool_tag')
class PoolLookup(LookupChannel):

    model = Pool

    def get_query(self, q, request):
        return self.model.objects.filter(name__icontains=q).order_by('name')[:50]

    def format_item_display(self, item):
        return u"<span class='tag'>%s</span>" % item.name

@register('index_tag')
class IndexLookup(LookupChannel):

    model = Index

    def get_query(self, q, request):
        return self.model.objects.filter(index_name__icontains=q).order_by('index_name')[:50]

    def format_item_display(self, item):
        return u"<span class='tag'>%s</span>" % item.index_name

@register('list_tag')
class IndexLookup(LookupChannel):

    model = GeneCandList

    def get_query(self, q, request):
        return self.model.objects.filter(name__icontains=q).order_by('name')[:50]

    def format_item_display(self, item):
        return u"<span class='tag'>%s</span>" % item.name**