Python 基于模型中的值创建URL
我想创建一个博客页面,它可以完美地工作,但我想更改特定博客文章的URL。目前,特定博客文章的URL是myurl.com/blog/pk,但我希望改为myurl.com/blog/category/title。我该怎么做?如果您喜欢,也请欣赏对代码的任何批评 型号.pyPython 基于模型中的值创建URL,python,django,Python,Django,我想创建一个博客页面,它可以完美地工作,但我想更改特定博客文章的URL。目前,特定博客文章的URL是myurl.com/blog/pk,但我希望改为myurl.com/blog/category/title。我该怎么做?如果您喜欢,也请欣赏对代码的任何批评 型号.py from django.db import models class Category(models.Model): name = models.CharField(max_length=20) class Post(
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
class Post(models.Model):
title = models.SlugField(max_length = 250, null = True, blank = True)
body = models.TextField()
created_on = models.DateTimeField(null=True)
last_modified = models.DateTimeField(null=True)
categories = models.ManyToManyField('Category', related_name='posts')
class Comment(models.Model):
author = models.CharField(max_length=60)
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE)
视图.py
from django.shortcuts import render
from .models import Post
from .models import Comment
from .forms import CommentForm
from django.http import HttpResponse
def blog_index(request):
posts = Post.objects.all().order_by('-created_on')
context = {
"posts": posts,
}
return render(request, "blog_index.html", context)
def blog_category(request, category):
posts = Post.objects.filter(
categories__name__contains=category
).order_by(
'-created_on'
)
if not posts:
return HttpResponse(status=404)
context = {
"category": category,
"posts": posts
}
return render(request, "blog_category.html", context)
def blog_detail(request, pk):
post = Post.objects.get(pk=pk)
form = CommentForm()
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment(
author=form.cleaned_data["author"],
body=form.cleaned_data["body"],
post=post
)
comment.save()
comments = Comment.objects.filter(post=post)
context = {
"post": post,
"comments": comments,
"form": form,
}
return render(request, "blog_detail.html", context)
from django.urls import path
from . import views
urlpatterns = [
path("", views.blog_index, name="blog_index"),
path("<int:pk>/", views.blog_detail, name="blog_detail"),
path("<category>/", views.blog_category, name="blog_category"),
]
应用程序URL.py
from django.shortcuts import render
from .models import Post
from .models import Comment
from .forms import CommentForm
from django.http import HttpResponse
def blog_index(request):
posts = Post.objects.all().order_by('-created_on')
context = {
"posts": posts,
}
return render(request, "blog_index.html", context)
def blog_category(request, category):
posts = Post.objects.filter(
categories__name__contains=category
).order_by(
'-created_on'
)
if not posts:
return HttpResponse(status=404)
context = {
"category": category,
"posts": posts
}
return render(request, "blog_category.html", context)
def blog_detail(request, pk):
post = Post.objects.get(pk=pk)
form = CommentForm()
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment(
author=form.cleaned_data["author"],
body=form.cleaned_data["body"],
post=post
)
comment.save()
comments = Comment.objects.filter(post=post)
context = {
"post": post,
"comments": comments,
"form": form,
}
return render(request, "blog_detail.html", context)
from django.urls import path
from . import views
urlpatterns = [
path("", views.blog_index, name="blog_index"),
path("<int:pk>/", views.blog_detail, name="blog_detail"),
path("<category>/", views.blog_category, name="blog_category"),
]
我确信你不想使用标题。标题通常可以包含空格(
)、标点(~!?
等)和特殊字符。URL不能包含这些字符中的大多数。确实可以避开这些字符,但URL看起来非常难看,如:
myurl.com/some%20title%20containing%20spaces
现在这不是很容易理解
但是,您可以使用一个slug和一个slug。一个SlugField
是一个CharField
,但是它会进行一些清理以避免丑陋的URL。例如,“包含空格的某些标题”
将转换为包含空格的某些标题
您可以将SlugField
添加到CategoryModel
中,如:
from django.utils.text import slugify
class Category(models.Model):
name = models.CharField(max_length=20)
slug = models.SlugField(unique=True, blank=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super().save(*args, **kwargs)
然后,我们可以从我们的角度对slug进行过滤:
from django.shortcuts import get_list_or_404
from .models import Post
def blog_category(request, category_slug):
posts = get_list_or_404(Post.objects.filter(
categories__slug=category_slug
).order_by(
'-created_on'
))
context = {
'category': category,
'posts': posts
}
return render(request, 'blog_category.html', context)
我确信你不想使用标题。标题通常可以包含空格(
)、标点(~!?
等)和特殊字符。URL不能包含这些字符中的大多数。确实可以避开这些字符,但URL看起来非常难看,如:
myurl.com/some%20title%20containing%20spaces
现在这不是很容易理解
但是,您可以使用一个slug和一个slug。一个SlugField
是一个CharField
,但是它会进行一些清理以避免丑陋的URL。例如,“包含空格的某些标题”
将转换为包含空格的某些标题
您可以将SlugField
添加到CategoryModel
中,如:
from django.utils.text import slugify
class Category(models.Model):
name = models.CharField(max_length=20)
slug = models.SlugField(unique=True, blank=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super().save(*args, **kwargs)
然后,我们可以从我们的角度对slug进行过滤:
from django.shortcuts import get_list_or_404
from .models import Post
def blog_category(request, category_slug):
posts = get_list_or_404(Post.objects.filter(
categories__slug=category_slug
).order_by(
'-created_on'
))
context = {
'category': category,
'posts': posts
}
return render(request, 'blog_category.html', context)
您不能使用标题,或者至少不建议使用,因为标题可以包含空格、标点符号等。通常使用slug。这很有意义。将我的模型字段从
Charfield
更改为slug
,是否会导致任何问题@WillemVanonSem通常您会为此添加一个slug
字段。您不能使用标题,或者至少不建议这样做,因为标题可以包含空格、标点符号等。通常情况下会使用slug。这很有意义。将我的模型字段从Charfield
更改为slug
,是否会导致任何问题@WilleMVanonSem通常您会为此添加一个slug
字段。运行migrate
会出现以下错误-django.db.utils.IntegrityError:UNIQUE constraint failed:new\uu blog\u category。slug
也不是blog\u detail()
?目前,blog\u category()
创建了一个页面,其中包含我想要的该类别下的所有帖子。我只想将单击的博客文章的最终url命名为MyUrl.com/blog/category/title
@LesnieSncheider:迁移失败的原因是您添加了一个额外的字段slug
,而现在该字段在所有记录中都不是唯一的。如果你想在博客
上找到slug,你确实应该将它添加到博客
模型中。我从类别
模型中删除了slug
,现在它仍然会引起同样的问题。@Lesniesdheider:是的,那是因为它仍然在迁移文件中,你也应该删除它。运行migrate
会给我以下错误-django.db.utils.integrityyror:UNIQUE约束失败:新建博客类别。slug
也不是blog\u detail()
决定特定博客文章的URL而不是blog\u类别()
?目前,blog\u category()
创建了一个页面,其中包含我想要的该类别下的所有帖子。我只想将单击的博客文章的最终url命名为MyUrl.com/blog/category/title
@LesnieSncheider:迁移失败的原因是您添加了一个额外的字段slug
,而现在该字段在所有记录中都不是唯一的。如果你想在博客
上找到slug,你确实应该将它添加到博客
模型中。我从类别
模型中删除了slug
,现在它仍然会导致同样的问题。@Lesniesdheider:是的,这是因为它仍然在迁移文件中,你也应该删除它。