如何在 url 中显示唯一生成的 slug

How to display uniquely generated slugs in urls

我希望我的 URL 显示 slug 而不是 id。在观看 Youtube 视频后,我到达了一个阶段,当我保存我的产品时,管理员会自动创建 slug。但我仍然不知道如何在细节视图的 url 中显示 slug。

我在我的项目文件夹中创建了一个 utils.py 并命名为 myawesomecart

import string
import random

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):
"""
This is for a Django project and it assumes your instance 
has a model with a slug field and a title character (char) field.
"""
if new_slug is not None:
    slug = new_slug
else:
    slug = slugify(instance.title)

Klass = instance.__class__
qs_exists = Klass.objects.filter(slug=slug).exists()
if qs_exists:
    new_slug = "{slug}-{randstr}".format(
        slug=slug,
        randstr=random_string_generator(size=4)
    )
    return unique_slug_generator(instance, new_slug=new_slug)
return slug

我的models.py文件如下

from django.db import models
from django.db.models.signals import pre_save #2 slug
from myawesomecart.utils import unique_slug_generator
# Create your models here.
class product(models.Model):
   
    title = models.CharField(max_length=50)
    slug= models.SlugField(max_length = 250, null = True, blank = True)
    category = models.CharField(max_length=50, default="your category here")
    subcategory = models.CharField(max_length=50, default= "your subcategory here")
    price = models.IntegerField(null=True)
    desc = models.CharField(max_length=500)
    pub_date = models.DateField()
    image = models.ImageField(upload_to="shop/images" , null= True)

    def __str__(self):
        return self.title
    
def slug_generator(sender,instance,*args, **kwargs):       #1 slug
    instance.slug = unique_slug_generator(instance)

pre_save.connect(slug_generator,sender = product)        #3 slug

urls.py 我的名为 shop

的应用程序的文件
from django.urls import path
from . import views
from . views import product_list_view, product_detail_view
urlpatterns = [
    path('',views.index,name='shophome'),
    path('about/',views.about,name='About us'),
    path('contact/',views.contact,name='contact'),
    path('tracker/',views.tracker,name='trackingstatus'),
    path('search/',views.search,name='search'),
    path('productview/',views.productview,name='productview'),
    path('checkout/',views.checkout,name='checkout'),
    path('list/',views.product_list_view,name='list'),
    path('checkout/',views.checkout,name='checkout'),
    path('<id>/',product_detail_view),
 
  

]

views.py 我的应用文件

from django.shortcuts import render,get_object_or_404 #get obj is for detailed view

from django.views.generic import ListView, DetailView
from . models import product
# Create your views here. b8
def index(request):
    return render(request,'shop/index.html')

def about(request):
    return render(request,'shop/index.html')

def contact(request):
    return render(request,'shop/index.html')

def tracker(request):
    return render(request,'shop/index.html')

def search(request):
    return render(request,'shop/index.html')

def productview(request):
    return render(request,'shop/index.html')

def checkout(request):
    return render(request,'shop/index.html')



def product_list_view(request):
 
    allproducts= product.objects.all() #allproduct is a variable ,kuch bhi likh lo yaha,aage jo product likha hai ye model hai apna
    
    context= {'allproducts': allproducts}  #variable pass hua hai bas

        
    return render(request, 'shop/listview.html', context)


def product_detail_view(request, id=None):

    allproducts= product.objects.get(id=id) #product.objects.all karne par 404 error milega
    
    context= {'allproducts': allproducts}

    
    return render(request, 'shop/detailview.html', context)




'''
#DETAILED VIEW
#detailedview baane ke bad listview ke html me change karna hoga

<h1>List of products</h1>

{% for product in allproducts %}
<!--#{{ product.product_name }} -->
<a href="/shop/{{product.id }}">{{ product.product_name }} </a>  #this is the change
<br><br>
{% endfor %}
</table>

'''

detailview.html 我的应用文件

<html>
<head>
<meta charset="UTF-8">
<title>Movies</title>
</head>
<body>




<h1><img src='{{ allproducts.image.url }}' class='img-fluid' /> </h1>


<p> {{ allproducts.title}}</p>

<p>{{ allproducts.category }}</p>

<p> {{ allproducts.price }}</p>

<p>Go back to the <a href="/shop/list/">list of products </a></p>

</body>
<script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'}),_trfd.push({'ap':'cpsh'},{'server':'p3plcpnl0769'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/tcc/tcc_l.combined.1.0.6.min.js'></script></html>

listview.html 应用文件

<html>
<head>
<meta charset="UTF-8">
<title>products</title>
</head>
<body>


<h1>List of products</h1>

{% for product in allproducts %}
<!--#{{ product.product_name }} -->
<a href="/shop/{{product.id }}">{{ product.title }} </a>
<br><br>
{% endfor %}
</table>


</body>
<script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'}),_trfd.push({'ap':'cpsh'},{'server':'p3plcpnl0769'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/tcc/tcc_l.combined.1.0.6.min.js'></script></html>

您必须在 url 模式中使用 slug 而不是 id

path('<slug>/',product_detail_view),

然后您必须更新您的视图以处理 slug 而不是 id

def product_detail_view(request, slug=None):
    allproducts= product.objects.get(slug=slug) #product.objects.all karne par 404 error milega
    
    context= {'allproducts': allproducts}

    return render(request, 'shop/detailview.html', context)

您还需要更新您的列表视图模板,以便使用 slugs 建立链接

<a href="/shop/{{product.slug }}">{{ product.title }} </a>