如何解决Triyng从Django博客中的标题帖子中获取URL
为将来的url设置了Slug变量,并进行了./makemigrations和迁移,并且参数显示在管理面板中,但是当我尝试进行空的“ theblog”迁移后尝试进行迁移时,出现此错误:
class Migration(migrations.Migration):
File "xxx/theblog/models.py",line 104,in Migration
migrations.RunPython(generate_slugs_for_old_posts,reverse=reverse_func),TypeError: __init__() got an unexpected keyword argument 'reverse'
将slug参数从null和blank更改为unique,但这现在似乎不是问题。我知道问题出在get_success_url,但真的不知道如何解决。
models.py:
from django.utils.text import slugify
class Post(models.Model):
title= models.CharField(max_length=100)
header_image = models.ImageField(null=True,blank=True,upload_to="images/")
title_tag= models.CharField(max_length=100)
author= models.ForeignKey(User,on_delete=models.CASCADE)
body = RichTextUploadingField(extra_plugins=
['youtube','codesnippet'],external_plugin_resources= [('youtube','/static/ckeditor/youtube/','plugin.js'),('codesnippet','/static/ckeditor/codesnippet/','plugin.js')])
post_date = models.DateTimeField(auto_Now_add=True)
category = models.CharField(max_length=50,default='uncategorized')
slug = models.SlugField(unique=True)
snippet = models.CharField(max_length=200)
status = models.IntegerField(choices=STATUS,default=0)
likes = models.ManyToManyField(User,related_name='blog_posts')
def save(self,*args,**kwargs):
self.slug = self.generate_slug()
return super().save(*args,**kwargs)
def generate_slug(self,save_to_obj=False,add_random_suffix=True):
generated_slug = slugify(self.title)
random_suffix = ""
if add_random_suffix:
random_suffix = ''.join([
random.choice(string.ascii_letters + string.digits)
for i in range(5)
])
generated_slug += '-%s' % random_suffix
if save_to_obj:
self.slug = generated_slug
self.save(update_fields=['slug'])
return generated_slug
def generate_slugs_for_old_posts(apps,schema_editor):
Post = apps.get_model("theblog","Post")
for post in Post.objects.all():
post.slug = slugify(post.title)
post.save(update_fields=['slug'])
def reverse_func(apps,schema_editor):
pass # just pass
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.RunPython(generate_slugs_for_old_posts,]
解决方法
首先,您必须向generate_slug(...)
模型添加可为空的子弹字段。这是Django docs的子弹字段。您还必须实现生成子弹值的方法。您可以在模型上实现import string # for string constants
import random # for generating random strings
# other imports ...
from django.utils.text import slugify
# other imports ...
class Post(models.Model):
# ...
slug = models.SlugField(null=True,blank=True,unique=True)
# ...
def save(self,*args,**kwargs):
self.slug = self.generate_slug()
return super().save(*args,**kwargs)
def generate_slug(self,save_to_obj=False,add_random_suffix=True):
"""
Generates and returns slug for this obj.
If `save_to_obj` is True,then saves to current obj.
Warning: setting `save_to_obj` to True
when called from `.save()` method
can lead to recursion error!
`add_random_suffix ` is to make sure that slug field has unique value.
"""
# We rely on django's slugify function here. But if
# it is not sufficient for you needs,you can implement
# you own way of generating slugs.
generated_slug = slugify(self.title)
# Generate random suffix here.
random_suffix = ""
if add_random_suffix:
random_suffix = ''.join([
random.choice(string.ascii_letters + string.digits)
for i in range(5)
])
generated_slug += '-%s' % random_suffix
if save_to_obj:
self.slug = generated_slug
self.save(update_fields=['slug'])
return generated_slug
方法,例如:
slug
现在,在保存每个对象时,您将自动为您的对象生成段塞。
处理未设置RunPython
字段的旧帖子。您必须使用python manage.py makemigrations <APP_NAME> --empty
(Django docs)创建自定义迁移:
首先运行此命令
Post
将{APP_NAME>替换为from django.utils.text import slugify
from django.db import migrations
def generate_slugs_for_old_posts(apps,schema_editor):
Post = apps.get_model("<APP_NAME>","Post") # replace <APP_NAME> with actual app name
# dummy way
for post in Post.objects.all():
# Do not try to use `generate_slug` method
# here,you probably will get error saying
# that Post does not have method called `generate_slug`
# as it is not the actual class you have defined in your
# models.py!
post.slug = slugify(post.title)
post.save(update_fields=['slug'])
def reverse_func(apps,schema_editor):
pass # just pass
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.RunPython(generate_slugs_for_old_posts,reverse=reverse_func),]
模型所在的实际应用名称。
它将生成一个空的迁移文件:
class Post(models.Model):
# ...
slug = models.SlugField(unique=True)
# ...
在那之后,您可以更改子弹字段并使其不可为空:
python manage.py migrate
现在(define li (list 'a 'b 'c 'd 'e))
(list? li)
;; -> #t
(set-cdr! (cddddr li) li) ;; list is now circular
(list? li)
;; -> #f
,这将使子句字段在以后的帖子中不为空,但是它可能会警告您说您正在尝试创建现有列
不可为空。在这里,您可以选择一个选项,上面写着“我已创建自定义迁移”或类似的内容。选择它。
现在,当您的帖子中有时,您必须修复视图,以便它们接受url中的参数。这里的技巧是确保您的帖子也可以被ID接受。由于已经有人可以链接到具有ID的帖子。如果您删除带有ID参数的URL,则可能导致某人无法再使用该旧链接。
,您还可以将旧网址重定向到新网址
urls.py
[..]
from django.views.generic.base import RedirectView
urlpatterns = [
# Redirect old links:
path('article/<int:pk>',RedirectView.as_view(url='article/<slug:url>',permanent=True)),# You won't need this path any more
# path('article/<int:pk>',ArticleDetailView.as_view(),name="article-detail"),# The new path with slug
path('article/<slug:url>',[..]
]
参阅https://docs.djangoproject.com/en/3.1/ref/class-based-views/base/#redirectview
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。