【问题标题】:Populate existing model objects with AutoSlugField使用 AutoSlugField 填充现有模型对象
【发布时间】:2018-08-26 14:52:44
【问题描述】:

我需要为已经存在的模型对象填充 AutoslugField。我的坏人意识到 slug 字段是如此方便和更好,以至于将 pk 用于安全目的。

我已经在数据库中有模型对象(行)。我想将 AutoSlugField 添加到它们。

任何人都知道我如何做到这一点。

谢谢

【问题讨论】:

  • 所以您想根据不同的字段(如标题等)为所有模型对象生成一个 slug?
  • 没错@xyres

标签: django django-extensions


【解决方案1】:

假设模型如下所示:

class MyModel(...):
    title = <Charfield>
    slug = <AutoSlugField>

您可以编写一个for 循环来读取MyModel 中的所有对象,并使用django.utils.text.slugifytitle 转换为slug。您可以在 shell 中运行它:

from django.utils.text import slugify

from myapp.models import MyModel


# The for loop to create new slugs and update db records

for obj in MyModel.objects.all():
    if not obj.slug: # only create slug if empty

        slug = slugify(obj.title)

        cycle = 1 # the current loop cycle

        while True:
            # this loop will run until the slug is unique
            try:
                model = MyModel.objects.get(slug=slug_text)
            except MyModel.DoesNotExist:
                obj.slug = slug
                obj.save()
                break
            else:
                slug = generate_another_slug(slug, cycle)

            cycle += 1 # update cycle number

generate_another_slug 函数可能如下所示:

def generate_another_slug(slug, cycle):
    """A function that takes a slug and 
    appends a number to the slug

    Examle: 
        slug = 'hello-word', cycle = 1
        will return 'hello-word-1'
    """
    if cycle == 1:
        # this means that the loop is running 
        # first time and the slug is "fresh"
        # so append a number in the slug
        new_slug = "%s-%s" % (slug, cycle)
    else:
        # the loop is running more than 1 time
        # so the slug isn't fresh as it already 
        # has a number appended to it
        # so, replace that number with the 
        # current cycle number
        original_slug = "-".join(slug.split("-")[:-1])
        new_slug = "%s-%s" % (original_slug, cycle)

    return new_slug

【讨论】:

  • 我认为有条件地接受这个答案。蛞蝓必须是唯一的,因此必须正确处理碰撞。否则感谢指针
  • 我已经测试过了,它不处理唯一性。我可以为两个我不想要的不同模型对象创建并保存相同的 slug。
  • 编辑答案以使用多个字段处理冲突或指示冲突,例如`slug_text = model_object.var1 + .... try: model=Model.objects.get(slug=slug_text) except DoesNotExist: modelobject.slug=slug_text modelobject.save() else look_for_anotjer_slug'
  • @unlockme 我已根据您的建议更新了答案。谢谢你。如果旧的 slug 不是唯一的,我还添加了另一个函数来生成新的 slug。
猜你喜欢
  • 2016-01-13
  • 2013-06-12
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多