C'è un modo semplice per popolare SlugField da CharField?
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.
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.