मैं Django में एक स्लग कैसे बनाऊं?


218

मैं SlugFieldDjango में एक बनाने की कोशिश कर रहा हूँ ।

मैंने यह सरल मॉडल बनाया:

from django.db import models

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

मैं फिर यह करता हूं:

>>> from mysite.books.models import Test
>>> t=Test(q="aa a a a", s="b b b b")
>>> t.s
'b b b b'
>>> t.save()
>>> t.s
'b b b b'

मैं उम्मीद कर रहा था b-b-b-b

जवाबों:


413

आपको slugify फ़ंक्शन का उपयोग करने की आवश्यकता होगी।

>>> from django.template.defaultfilters import slugify
>>> slugify("b b b b")
u'b-b-b-b'
>>>

आप विधि slugifyको ओवरराइड करके स्वचालित रूप से कॉल कर सकते हैं save:

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

    def save(self, *args, **kwargs):
        self.s = slugify(self.q)
        super(Test, self).save(*args, **kwargs)

ध्यान रखें कि उपरोक्त आपके URL को qफ़ील्ड संपादित करने पर बदलने का कारण होगा , जो टूटे हुए लिंक का कारण बन सकता है । जब आप कोई नई वस्तु बनाते हैं तो केवल स्लग उत्पन्न करना बेहतर हो सकता है:

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

    def save(self, *args, **kwargs):
        if not self.id:
            # Newly created object, so set slug
            self.s = slugify(self.q)

        super(Test, self).save(*args, **kwargs)

4
शर्मीली एक विशेष मॉडल प्रकार है? क्यों नहीं सिर्फ CharFields सुस्त?
जोहड

23
SlugFields डिफ़ॉल्ट रूप से db_index = True सेट करता है, और डिफ़ॉल्ट रूप से एक प्रपत्र फ़ील्ड का भी उपयोग करता है जिसमें वैध स्लग की आवश्यकता होती है (यदि एक मॉडलफ़ॉर्म में या व्यवस्थापक में प्रतिनिधित्व किया गया है)। आप उन चीजों को मैन्युअल रूप से एक CharField के साथ कर सकते हैं यदि आप पसंद करते हैं, तो यह आपके कोड के इरादे को कम स्पष्ट करता है। इसके अलावा, Prepopulate_fields ModelAdmin सेटिंग को न भूलें, यदि आप जेएस-आधारित ऑटो-प्रॉपोपॉलेट को व्यवस्थापक में चाहते हैं।
कार्ल मेयर

4
के रूप में डिंगल उसके जवाब में नीचे ने कहा, आप बदलना भी होगा def save(self):साथ def save(self, *args, **kwargs):फेंक दिया जा रहा है जब की तरह कुछ लिखने से बचने के लिए त्रुटियों के क्रम में test.objects.create(q="blah blah blah")
लियाम

6
सावधान रहें कि यह कोड प्रत्येक सेव के स्लग को अपडेट करेगा। आपका url बदल जाएगा, और "Cool URIs नहीं बदलेगा" w3.org/Provider/Style/URI.html
dzen

18
slugify()में भी पाया जा सकता है django.utils.text.slugify, स्पष्ट नहीं है जब यह जोड़ा गया था।
mrmagooey

112

कुछ utf-8 अक्षरों के साथ कोने का मामला है

उदाहरण:

>>> from django.template.defaultfilters import slugify
>>> slugify(u"test ąęśćółń")
u'test-aescon' # there is no "l"

इसे यूनीडॉब के साथ हल किया जा सकता है

>>> from unidecode import unidecode
>>> from django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u'test-aescoln'

7
utf-8 को अब सही ढंग से slugify (django 1.8.5 में) द्वारा संभाला गया है
रिक वेस्टेरा

जैसा कि @RickWestera ने कहा कि यह अब slugify द्वारा संभाला जाता है, हालाँकि अगर किसी कारण से आप slugify का उपयोग नहीं करना चाहते हैं, तो django.utils.encoding से iri_to_uri की जाँच करें: docs.djangopodject.com/en/2.0/ref/unicode/…
एरवोल

64

थेपेर के उत्तर में एक छोटा सा सुधार: save()मॉडल कक्षाओं में कार्य को ओवरराइड करने के लिए , इसमें बेहतर तर्क जोड़ें:

from django.utils.text import slugify

def save(self, *args, **kwargs):
    if not self.id:
        self.s = slugify(self.q)

    super(test, self).save(*args, **kwargs)

अन्यथा, test.objects.create(q="blah blah blah")एक force_insertत्रुटि (अप्रत्याशित तर्क) में परिणाम होगा ।


2
एक और बहुत मामूली बात करने के लिए उत्तरदाता को जोड़ने के लिए: मैं उस अंतिम पंक्ति बनाना होगा return super(test, self).save(*args, **kwargs)। मुझे लगता है कि यह विधि लौटती है None, और मुझे इसे बदलने की किसी भी योजना के बारे में पता नहीं है, लेकिन सुपरक्लॉस की विधि भविष्य में कभी-कभी इसे बदलने की स्थिति में क्या करती है, इसे वापस करने में कोई बुराई नहीं है।
डंकन पार्क

कृपया जोड़ दें कि इस समाधान के लिए django.utils.text आयात slugify से आवश्यक है।
राउटरिनेटर

1
@ राउटरिनेटर ने किया
जोनास

कुछ महसूस करने वालों को यह पूछना कि क्या यह अभी भी ऐसा करने के लिए एक पसंदीदा तरीका है।
sytech

29

आप अपने मॉडल की नए आइटम जोड़ने के व्यवस्थापक इंटरफ़ेस का उपयोग कर रहे हैं, तो आप एक सेट कर सकते हैं ModelAdminअपने में admin.pyऔर उपयोग prepopulated_fieldsएक स्लग के प्रवेश करने को स्वचालित करने के:

class ClientAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Client, ClientAdmin)

यहां, जब उपयोगकर्ता nameफ़ील्ड के लिए व्यवस्थापक फ़ॉर्म में एक मूल्य दर्ज करता है , तो slugस्वचालित रूप से सही स्लैगिफ़ाइड के साथ आबादी आ जाएगी name


मेरे slugऔर nameखेतों में अनुवाद हैं। मैं अनुवादों के साथ ऐसा कैसे कर सकता हूं? क्योंकि मैंने जोड़ने की कोशिश की है 'slug_en':('name_en',)और त्रुटि मिली है कि विशेषता मेरे मॉडल में मौजूद नहीं है।
पेट्रीसिया

22

ज्यादातर मामलों में स्लग को बदलना नहीं चाहिए, इसलिए आप वास्तव में केवल पहली बचत पर इसकी गणना करना चाहते हैं:

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField(editable=False) # hide from admin

    def save(self):
        if not self.id:
            self.s = slugify(self.q)

        super(Test, self).save()

6

prepopulated_fieldsअपने व्यवस्थापक वर्ग में उपयोग करें :

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

admin.site.register(Article, ArticleAdmin)

1
क्या आप समझाएँगे? व्यवस्थापक परियोजना को कैसे प्रभावित करता है?
ब्रायस

5

यदि आप स्लगफील्ड को संपादन योग्य नहीं बनाना चाहते हैं, तो मेरा मानना ​​है कि आप अशक्त और रिक्त गुणों को गलत पर सेट करना चाहते हैं। अन्यथा आपको व्यवस्थापक में सहेजने का प्रयास करते समय एक त्रुटि मिलेगी।

तो उपरोक्त उदाहरण में एक संशोधन होगा ::

class test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField(null=True, blank=True) # Allow blank submission in admin.

    def save(self):
        if not self.id:
            self.s = slugify(self.q)

        super(test, self).save()


4

मैं Django 1.7 का उपयोग कर रहा हूं

इस तरह से अपने मॉडल में एक स्लगफिल्ड बनाएं:

slug = models.SlugField()

फिर admin.pyपरिभाषित करने में prepopulated_fields;

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

वास्तव में मैं क्या चाहता था
निक

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.