没有app标签的django中基于标题的Slug

时间:2016-06-19 07:43:31

标签: regex django django-urls

我用ListView和DetailView获得了产品应用程序。我需要在详细信息页面上实现带有产品标题的slug,而url中没有app标签。比如在详细页面中它应该说'mysite.com/complete-product-title'而不是'mysite.com/products/complete-product-title'。这个详细页面可以帮助我解决SEO问题。

以下是代码:

models.py:

class Product(models.Model):
    title = models.CharField(max_length=500)
    description = models.TextField(blank=True, null=True)
    price = models.DecimalField(max_digits=20, decimal_places=2)
    sku = models.CharField(null=True, max_length=100)
    url = models.URLField(blank=True)
    slug = models.SlugField(default='')
    categories = models.ManyToManyField('Category', blank=True)
    default = models.ForeignKey('Category', related_name='default_category', null=True, blank=True)

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super().save(*args, **kwargs)


    def get_absolute_url(self):
        kwargs={"slug": self.slug}
        return reverse('product_detail', kwargs=kwargs)

Views.py:

class ProductListView(ListView):
    model = Product
    paginate_by = 20

    def get_context_data(self, *args, **kwargs):
        context = super(ProductListView, self).get_context_data(*args, **kwargs)
        return context

    def get_queryset(self, *args, **kwargs):
        query = super(ProductListView, self).get_queryset(*args, **kwargs)
        return query

class ProductDetailView(DetailView):
    model = Product
    slug_field = 'slug'

项目urls.py:

url(r'^products/', include('products.urls')),

App urls.py:

url(r'^(?P<slug>[\w-]+)/$', ProductDetailView.as_view(), name='product_detail'),

我已经用haystack实现了elasticsearch,为此我必须在项目根urls.py中添加haystack url,如url(r'^$', include('haystack.urls'), name='search'),

我的产品应用的完整models.py是

class Product(models.Model):
    title = models.CharField(max_length=500)
    description = models.TextField(blank=True, null=True)
    price = models.DecimalField(max_digits=20, decimal_places=2)
    sku = models.CharField(null=True, max_length=100)
    url = models.URLField(blank=True)
    slug = models.SlugField(unique=False)
    categories = models.ManyToManyField('Category', blank=True)
    default = models.ForeignKey('Category', related_name='default_category', null=True, blank=True)

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('product_detail', kwargs={"slug":self.slug})

    def get_image_url(self):
        img = self.productimage_set.first()
        if img:
            return img.image.url
        return img

class Category(models.Model):
    title = models.CharField(max_length=120, unique=True)
    #slug = models.SlugField(unique=True)
    description = models.TextField(null=True, blank=True)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __unicode__(self):
        return self.title

def image_upload_to(instance, filename):
    title = instance.product.title
    slug = slugify(title)
    basename, file_extension = filename.split('.')
    new_filename = '%s-%s.%s'%(basename, instance.id, file_extension)
    return 'products/%s/%s' %(slug, new_filename)
class ProductImage(models.Model):
    product = models.ForeignKey(Product)
    image = models.ImageField(upload_to=image_upload_to)

    def __unicode__(self):
        return self.product.title

当我尝试添加slug=models.SlugField(unique=True)时,收到错误消息,例如column slug is not unique

现在我无法从products/删除url(r'^products/', include('products.urls')),因为它会使干草堆网址和产品应用网址都默认。这里的最终目标是默认实施haystack网址,但不显示'mysite.com/products/product-title-as-slug' 'mysite.com/product-title-as-slug'

请协助我如何实现这一目标。

1 个答案:

答案 0 :(得分:0)

您可以通过更改:

立即执行此操作
url(r'^products/', include('products.urls')),

url(r'^', include('products.urls')),

如果您的网站尚未投放,则需要执行此操作。否则,您还应该将旧网址(mysite.com/products/complete-product-title)的301重定向同时写入您的新网址。