我正在尝试使用slug url,例如/ post / 5post-title或/ post / post-title。 我目前使用/ post / 123形式的纯URL,我尝试了很多方法,但都失败了.. 现在我正在尝试从https://keyerror.com/blog/slug-fields-an-alternative-approach
“从基于主键的查找迁移”我得到了一个错误的错误'太多重定向'...如何解决这个问题?或者你有更好的方法来改变普通网址到slug url?
我的模特:
class Post(models.Model):
title,article and someFields.......
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:detail',kwargs={'pk':self.pk})
def slug(self):
return slugify(self.title)
和我的网址:
urlpatterns=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^post/(?P<pk>[0-9]+)(?:/(?P<slug>[\w-]+))?$',views.detail,name='detail'),]
我的观点:
def detail(request,pk,slug=None):
post=get_object_or_404(Post,pk=pk)
if slug!=post.slug():
return redirect(post, permanent=True)
return render(request,'blog/detail.html',context=context)
使用SlugField模型并删除pk:
class Post(models.Model):
title=models.CharField(max_length=70)
body=models.TextField()
created_time=models.DateTimeField()
modified_time=models.DateTimeField()
excerpt=models.CharField(max_length=200,blank=True)
category=models.ForeignKey(Category)
tags=models.ManyToManyField(Tag,blank=True)
author=models.ForeignKey(User)
views=models.PositiveIntegerField(default=0)
excerpt=models.CharField(max_length=100,blank=True)
sluglookup = models.SlugField(
unique=True,
default=Post.slug,
max_length=15,)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:detail',kwargs={'pk':self.pk})
def increase_views(self):
self.views+=1
self.save(update_fields=['views'])
def save(self,*args,**kwargs):
if not self.excerpt:
md=markdown.Markdown(extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
])
self.excerpt=strip_tags(md.convert(self.body))[:54]
super(Post,self).save(*args,**kwargs)
def slug(self):
return slugify(self.title)
答案 0 :(得分:0)
我怀疑循环是一个问题,不是你的slug逻辑,而是你的404页面逻辑。基于以上所述,您错误地使用了这些网址。你的正则表达式查找/post/<pk>/<slug>
。您使用的是网址/post/<pk><slug>
(请注意额外的/
)。因此/post/5post-title
应该是/post/5/post-title
。
另外,如果您真的对使用基于slug的纯系统感兴趣,那么您应该使用SlugField
,如下例所示,并完全删除主键。
lookup = models.SlugField(
unique=True,
default=self.slug, # This is not from the tutorial, it's a modification
# to demonstrate here.
max_length=13,
)
然后您需要一个网址:
url(r'^post/(?P<slug>[\w-]+)?$',views.detail,name='detail'),
观点:
def detail(request,slug=None):
post=get_object_or_404(Post,lookup=slug)
# You probably have to pass the post into the render function, that
# will vary, based on how you've defined it in your template
return render(request,'blog/detail.html',context=context)