Domanda

django-ajax-seleziona , che è un app Django fornisce funzionalità di completamento automatico jQuery liberamente disponibile.

Non ho capito di lavoro - cioè si autocompleting i campi del modulo voglio che. Ma ho un problema ... lo sto usando in un ModelForm che aggiunge gli oggetti di partenariato alla base di dati:

class Skater(models.Model):
    name = models.CharField(max_length=64)
    surname = models.CharField(max_length=64)
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

class Partnership(models.Model):
    female_partner = models.ForeignKey(Skater, limit_choices_to = {'gender': FEMALE}, related_name='female_partner_set')
    male_partner = models.ForeignKey(Skater, limit_choices_to = {'gender': MALE}, related_name='male_partner_set')

Voglio che l'utente sia in grado di mettere in un nome e cognome nel campo female_partner e male_partner anche se un oggetto del pattinatore del genere non esiste e voglio che oggetto creato. Come procedo a fare questo? Non riesco a mettere il codice nel metodo Save del form, perché il campo non convaliderà (non è un atleta valido).

Modifica 1: L'aggiunta in più codice ...

La forma:

class PartnershipAddForm(forms.ModelForm):
    female_partner = AutoCompleteSelectField('female_skater',required=True)
    male_partner = AutoCompleteSelectField('male_skater',required=True)

    class Meta:
        model = Partnership

settings.py:

AJAX_LOOKUP_CHANNELS = {
    'female_skater' : ('skaters.lookups', 'FemaleLookup'),
    'male_skater' : ('skaters.lookups', 'MaleLookup'),
}

lookups.py (MaleLookup è lo stesso, tranne che il sesso = maschio):

class FemaleLookup(object):

    def get_query(self,q,request):
        """ return a query set.  you also have access to request.user if needed """
        return Skater.objects.filter(Q(gender=FEMALE) & (Q(name__istartswith=q) | Q(surname__istartswith=q)))

    def format_item(self,skater):
        """ simple display of an object when it is displayed in the list of selected objects """
        return unicode(skater)

    def format_result(self,skater):
        """ a more verbose display, used in the search results display.  may contain html and multi-lines """
        return "%s<br/>" % unicode(skater)

    def get_objects(self,ids):
        """ given a list of ids, return the objects ordered as you would like them on the admin page.
            this is for displaying the currently selected items (in the case of a ManyToMany field)
        """
        return Skater.objects.filter(pk__in=ids).order_by('name','surname')
È stato utile?

Soluzione

AutoCompleteSelectField contiene l'ID dell'oggetto piuttosto che il testo, che è il motivo per cui ho avuto l'errore "necessaria" per tutto il tempo (e il motivo per cui la soluzione di Daniel non funziona). La variabile valore era vuoto come un atleta che non esiste non ha un id.

Non sono sicuro che questo è il modo migliore di fare questo, ma ho finito per usare AutoCompleteField invece di AutoCompleteSelectField. AutoCompleteField contiene il testo, ma non crea un oggetto Skater per me.

Il codice:

class PartnershipAddForm(forms.ModelForm):
    female_partner = AutoCompleteField('female_skater',required=True)
    male_partner = AutoCompleteField('male_skater',required=True)

    class Meta:
        model = Partnership

    def save(self):
        partners = [self.cleaned_data['female_partner'],
                    self.cleaned_data['male_partner']]
        name = ['','']
        surname = ['','']
        for i in [0,1]:
            name[i],surname[i] = get_name_surname(partners[i])
        partners = [None,None]
        partners_created = [None,None]
        gender = [FEMALE,MALE]
        for i in [0,1]:        
            partners[i],partners_created[i] = Skater.objects.get_or_create(
                                            name=name[i],
                                            surname=surname[i],
                                            gender=gender[i]
                                        )

         partnership, created = Partnership.objects.get_or_create(
                                    female_partner=partners[0],
                                    male_partner=partners[1],
                                )
         return partnership

Altri suggerimenti

Sembra che tu abbia bisogno di sottoclasse AutoCompleteSelectField da Ajax-seleziona e ignorare il suo metodo clean.

def clean(self, value):
    if value:
        lookup = get_lookup(self.channel)
        objs = lookup.get_objects( [value] )
        if objs:
            return objs[0]
        else:
            firstname, surname = value.split(" ")
            gender = self.channel.split("_")[0]
            new_skater = Skater(name=firstname, surname=surname, gender=gender)
            return new_skater
    else:
        if self.required:
            raise forms.ValidationError(self.error_messages['required'])
        return None

Possiamo vedere che la vostra forma assomiglia? Penso che è necessario in modo da qualcosa come sovrascrivere il metodo save () nel ModelForm, in modo da risparmiare il female_partner e male_partner prima, quindi salva l'istanza modulo (aka esempio Parntership).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top