在Django模型中添加slug字段

在Django模型中添加slug字段

什么是Django中的SlugField

它是一种生成有效URL的方法,一般使用已经获得的数据。例如,使用一篇文章的标题来生成一个URL。让我们假设我们的博客有一篇文章,标题为’The Django book by Geeksforgeeks’,主键id=2。我们可以用以下方式来引用这个帖子

www.geeksforgeeks.org/posts/2. 

或者,我们可以引用标题,如

 www.geeksforgeeks.org/posts/The Django book by Geeksforgeeks. 

但问题是空格在URL中是无效的,需要用%20代替,这很难看,使之成为以下内容

www.geeksforgeeks.org/posts/The%20Django%20book%20by%20geeksforgeeks 

但这并不能解决有意义的URL。另一个选项可以是

 www.geeksforgeeks.org/posts/the-django-book-by-geeksforgeeks

因此,现在的标题是the-django-book-by-geeksforgeeks。所有的字母都是小写的,空格则由连字符–取代。

假设我们的博客文章模型看起来与此类似。

STATUS_CHOICES = (
   ('draft', 'Draft'),
   ('published', 'Published'),
)
 
class Post(models.Model):
   title = models.CharField(max_length = 250)
   slug = models.SlugField(max_length = 250, null = True, blank = True)
   text = models.TextField()
   published_at = models.DateTimeField(auto_now_add = True)
   updated = models.DateTimeField(auto_now = True)
 
   status = models.CharField(max_length = 10, choices = STATUS_CHOICES,
                                                      default ='draft')
 
 
   class Meta:
       ordering = ('-published_at', )
 
   def __str__(self):
       return self.title

将Slugify加入到我们的项目中:

现在我们需要找到一种方法,将标题自动转换为蛞蝓。我们希望这个脚本在每次创建Post模型的新实例时被触发。为了这个目的,我们将使用信号。

注意:在保存settings.py文件的同一目录下添加新文件util.py。

import string, random
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.text import slugify
 
def random_string_generator(size = 10, chars = string.ascii_lowercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))
 
def unique_slug_generator(instance, new_slug = None):
    if new_slug is not None:
        slug = new_slug
    else:
        slug = slugify(instance.title)
    Klass = instance.__class__
    max_length = Klass._meta.get_field('slug').max_length
    slug = slug[:max_length]
    qs_exists = Klass.objects.filter(slug = slug).exists()
     
    if qs_exists:
        new_slug = "{slug}-{randstr}".format(
            slug = slug[:max_length-5], randstr = random_string_generator(size = 4))
             
        return unique_slug_generator(instance, new_slug = new_slug)
    return slug

Django中的信号:

在很多情况下,当一个模型的实例发生修改时,我们需要执行一些动作。Django为我们提供了一种优雅的方式来处理这些情况。信号是允许将事件与动作联系起来的实用工具。我们可以开发一个函数,当一个信号调用它时,它就会运行。
在post应用程序的models.py文件中,在定义了Post Model的地方,在同一个文件中添加这个。

@receiver(pre_save, sender=Post)
def pre_save_receiver(sender, instance, *args, **kwargs):
   if not instance.slug:
       instance.slug = unique_slug_generator(instance)

pre_save_receiver函数应该被单独放在Post模型之外。

注意:在urls.py中用path(‘post/’, detail)编辑detail路径。在views.py中编辑detail函数,用

def detail(request, slug):
    q = Post.objects.filter(slug__iexact = slug)
   if q.exists():
       q = q.first()
   else:
       return HttpResponse('<h1>Post Not Found</h1>')
   context = {
 
       'post': q
   }
   return render(request, 'posts/details.html', context)

最后一步是在HTML文件<a href=”/posts/{{ a.slug }}” class=”btn btn-primary”>视图</a>中添加链接。现在我们准备去127.0.0.1:8000/posts/title-you-have-added,它将向你展示details.html的页面。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程