2009-09-29 8 views
7

Attualmente sto lavorando a un progetto di giocattoli in Django.URL slangificati di Django - come gestire le collisioni?

Parte della mia app consente agli utenti di lasciare recensioni. Mi piacerebbe prendere il titolo della recensione e inserirlo per creare un URL.

Quindi, se un utente scrive una recensione chiamata "La cosa migliore di sempre!", L'url dovrebbe essere qualcosa come: www.example.com/reviews/the-best-thing-ever.

Questo va tutto bene, ma qual è il modo migliore per gestire casi in cui due utenti scelgono lo stesso titolo? Non voglio rendere il titolo richiesto per essere unico.

Ho pensato di aggiungere l'id di revisione nell'URL da qualche parte, ma vorrei evitare le informazioni aggiuntive per eventuali URL che non entrano in collisione.

Qualche idea?

risposta

6

Una cosa che non mi è mai piaciuta dei campi/metodi slug univoci è che se hai un sacco di conflitti per un singolo titolo, finirai per eseguire diverse query per cercare di determinare uno slug disponibile. So che hai detto che non vuoi mostrare l'id per le lumache non contrastanti, ma, per quanto riguarda le prestazioni, penso che sia la strada migliore da percorrere. Per rendere l'URL un po 'più bello, preferisco anche incorporare l'id prima dello slug, in modo che un URL abbia la forma di www.example.com/reviews/1/the-best-thing-ever.

+0

Questa è la soluzione Stavo considerando, anche se in questo caso, la lumaca si rivela essere un piacere per gli occhi senza senso. È veloce e ti libera completamente da questo problema. In una app "vera" probabilmente prenderei questa strada, ma sono comunque interessato a come si gestirà questo e permetterò comunque agli url non in collisione di essere totalmente liberi da qualsiasi id. –

+1

Dovrei anche notare che questo sembra essere lo stesso approccio che usa SO, se guardi la barra dell'URL :) –

+0

Beh, sembra che io sia in buona compagnia allora. Per quanto riguarda l'eliminazione di tutti gli ID, le altre due risposte sono sicuramente la strada da percorrere. Quando ho originariamente iniziato a fare slugging, ho usato un metodo slug unico che ho trovato da qualche parte (è quasi identico a quello pubblicato da Zalew). – Adam

2
from django.template.defaultfilters import slugify 

def slugify_unique(value, model, slugfield="slug"): 
     suffix = 0 
     potential = base = slugify(value) 
     while True: 
      if suffix: 
       potential = "-".join([base, str(suffix)]) 
      if not model.objects.filter(**{slugfield: potential}).count(): 
       return potential 
      suffix += 1  
""" 
above function is not my code, but i don't remember exactly where it comes from 
you can find many snippets with such solutions searching for 'unique slug' and so 
""" 


class ReviewForm(forms.ModelForm): 

    def save(self, user, commit=True):  
     self.instance.slug = slugify_unique(self.cleaned_data['title'], self.Meta.model)      
     review = super(ReviewForm, self).save(commit) 
     review.save() 
     return review 

    class Meta: 
     model = Review 

ovviamente cambiare i nomi appropriati e di definizione del modulo, ma si ottiene l'idea :)

6

Suggerirei qualcosa come AutoSlugField. Ha alcune opzioni disponibili rispetto alla configurazione dell'unicità (unique e unique_with) e ha il vantaggio di essere in grado di generare automaticamente lumache basate su un altro campo sul modello, se lo si desidera.

0

vorrei (nella validazione dei form) basta controllare per vedere se si utilizza la lumaca, e quindi aggiungere qualcosa ad esso, o un numero "my-cool-idea_2" o l'id effettivo