Domanda

class Foo(models.Model):
    title = models.CharField(max_length=20)
    slug = models.SlugField()

Esiste un modo integrato per far sì che il campo della lumaca si copra automaticamente in base al titolo? Forse nell'amministratore e all'esterno dell'amministratore.

È stato utile?

Soluzione

per Admin in Django 1.0 e versioni successive, dovresti utilizzare

prepopulated_fields = {'slug': ('title',), }

nel tuo admin.py

La tua chiave nel dizionario prepopulated_fields è il campo che vuoi riempire, e il valore è una tupla di campi che vuoi concatenare.

Al di fuori dell'amministratore, puoi usare la funzione slugify nelle tue viste. Nei modelli è possibile utilizzare il filtro | slugify .

Esiste anche questo pacchetto che si occuperà automaticamente di questo: https: //pypi.python .org / PyPI / django-autoslug

Altri suggerimenti

All'esterno dell'amministratore, vedi questo frammento di django . Inseriscilo nel tuo .save () e funzionerà con oggetti creati a livello di codice. All'interno dell'amministratore, come hanno detto gli altri, usa prepopulated_fields .

Per pre-1.0:

slug = models.SlugField(prepopulate_from=('title',))

dovrebbe funzionare bene

Per 1.0, utilizzare camflan's

Puoi anche usare il segnale django pre_save per popolare la lumaca al di fuori del codice admin di django. Vedi Documentazione sui segnali di Django .

Anche la convalida dell'unicità di slug Ajax sarà utile, vedi Convalida dell'unicità delle lumache As-You-Type @ Irrational Exuberance

autoslug ha funzionato abbastanza bene per me in passato. Anche se non ho mai provato a usarlo con l'app di amministrazione.

Ho pensato di aggiungere una risposta completa e aggiornata con i gotcha menzionati:

1. Popolare automaticamente i moduli in Django Admin

Se sei preoccupato solo di aggiungere e aggiornare i dati nell'amministratore, puoi semplicemente usare prepopulated_fields attributo

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

admin.site.register(Article, ArticleAdmin)

2. Popolare automaticamente i moduli personalizzati nei modelli

Se hai creato la tua interfaccia renderizzata dal server con i moduli, puoi popolare automaticamente i campi usando | slugify filtro tamplate o utilità slugify quando si salva il modulo (is_valid).

3. Popolazione automatica di campi slug a livello di modello con django-autoslug

Le soluzioni precedenti popoleranno automaticamente il campo slug (o qualsiasi altro campo) quando i dati vengono manipolati attraverso tali interfacce (l'amministratore o un modulo personalizzato). Se disponi di un'API, di comandi di gestione o di qualsiasi altra cosa che manipola anche i dati, devi scorrere a livello di modello.

django-autoslug fornisce i campi AutoSlugField che estendono SlugField e consentono di impostare quale campo dovrebbe essere accuratamente ordinato:

class Article(Model):
    title = CharField(max_length=200)
    slug = AutoSlugField(populate_from='title')

Il campo utilizza i segnali pre_save e post_save per ottenere la sua funzionalità, quindi per favore vedi il testo del gotcha in fondo a questa risposta.

4. Popolamento automatico dei campi slug a livello di modello sovrascrivendo save ()

L'ultima opzione è implementarla da soli, il che implica la sostituzione del metodo save () predefinito:

    class Article(Model):
        title = CharField(max_length=200)
        slug = SlugField()

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Job, self).save(*args, **kwargs)

NOTA: gli aggiornamenti collettivi ignoreranno il tuo codice (compresi i segnali)

Questa è una comprensione comune da parte dei principianti di Django. Prima di tutto dovresti sapere che i segnali pre_save e post_save sono direttamente correlati al metodo save (). In secondo luogo, i diversi modi di eseguire aggiornamenti di massa in Django eludono tutti il ??metodo save () - per ottenere prestazioni elevate, operando direttamente sul livello SQL. Ciò significa che per il modello di esempio utilizzato nella soluzione 3 o 4 sopra:

  • Article.objects.all (). update (title = 'New post') NOT aggiornerà la lumaca di qualsiasi articolo
  • Utilizzo di bulk_create o bulk_update sul modello dell'articolo NOT aggiorna la lumaca di qualsiasi articolo.
  • Poiché il metodo save () - non viene chiamato, non verranno emessi segnali pre_save o post_save .

Per eseguire aggiornamenti in blocco e utilizzare comunque i vincoli a livello di codice, l'unica soluzione è iterare gli oggetti uno per uno e chiamare il suo metodo save (), che ha prestazioni notevolmente inferiori rispetto alle operazioni in blocco a livello di SQL. Ovviamente potresti usare i trigger nel tuo database, anche se questo è un argomento completamente diverso.

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