Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django-为每个模型对象生成随机、唯一的slug字段_Python_Django_Slug - Fatal编程技术网

Python Django-为每个模型对象生成随机、唯一的slug字段

Python Django-为每个模型对象生成随机、唯一的slug字段,python,django,slug,Python,Django,Slug,我在Django中有一个名为ExampleModel的模型,希望每个模型对象都被唯一标识。但是,我不希望用户在URL中看到对象的ID;因此,我希望objectsslug是一个唯一的、随机生成的8位整数,它将出现在视图URL中。这与我看到的其他问题不同,因为这意味着不生成基于模型对象名称//内容本身的段塞字符串 Models.py: class ExampleModel(models.Model): user = models.ForeignKey(UserModel, related_n

我在Django中有一个名为
ExampleModel
的模型,希望每个模型对象都被唯一标识。但是,我不希望用户在URL中看到对象的ID;因此,我希望objects
slug
是一个唯一的、随机生成的8位整数,它将出现在视图URL中。这与我看到的其他问题不同,因为这意味着不生成基于模型对象名称//内容本身的段塞字符串

Models.py:

class ExampleModel(models.Model):
    user = models.ForeignKey(UserModel, related_name='examplemodel', on_delete=models.CASCADE, null=True)
    title = models.CharField(max_length=50, verbose_name='Title')
    slug = models.SlugField(unique=True, blank=True, null=True)
当前slug的值为null,因此我不必为所有当前
ExampleModel
对象设置默认slug

这是相当模糊的,可以理解,但我还没有找到任何指南/教程,可能适合我的具体情况

感谢您提供的任何帮助/指导

编辑 以下是我的观点.py:

def model_create(request):
    user=request.user.id
    if request.user.is_authenticated:
        try:
            example = request.user.examplemodel
        except ExampleProfile.DoesNotExist:
            example = ExampleProfile(user)
        if request.method == 'POST':
            form = NewForm(request.POST, request.FILES)
            if form.is_valid():
                form.save()
                return redirect('/dashboard/')
            else:
                return render(request, 'create.html', {'form': form})
        else:
            form = NewForm()
            return render(request, 'create.html', {'form': form})
    else:
        return redirect('/users/login/?next=')
编辑2Models.py(保存方法):

覆盖保存:

def save(self, *args, **kwargs):
    try:
        self.slug = ''.join(str(random.randint(0, 9)) for _ in range(8))
        super().save(*args, **kwargs)
    except IntegrityError:
        self.save(*args, **kwargs)
但是,这可能需要更多的保护措施来防止
IntegrityError
s。 如果您可以接受两次储蓄:

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    try:
        self.slug = ''.join(str(random.randint(0, 9)) for _ in range(8))
        super().save(*args, **kwargs)
    except IntegrityError:
        self.save(*args, **kwargs)

Django内置了一个
get_random_string
函数,可以生成slug所需的随机字符串

正如Sebastian Wozny提到的,您希望在重写save方法时调用它。基本原则是:

from django.utils.crypto import get_random_string
# ...
the_slug = get_random_string(8,'0123456789') # 8 characters, only digits. 
这不是实际的工作代码。更详细地说,真正的models.py如下所示。请注意,我并没有将自己限制在数字范围内,我正在做一项检查,检查是否有不连续性,并确保它不会拼写任何错误:

from django.db import models
from django.utils.crypto import get_random_string
# ...
class SomeModelWithSlug(models.Model):
  slug = models.SlugField(max_length=5,blank=True,) # blank if it needs to be migrated to a model that didn't already have this 
  # ...
  def save(self, *args, **kwargs):
    """ Add Slug creating/checking to save method. """
    slug_save(self) # call slug_save, listed below
    Super(SomeModelWithSlug, self).save(*args, **kwargs)
# ...
def slug_save(obj):
""" A function to generate a 5 character slug and see if it has been used and contains naughty words."""
  if not obj.slug: # if there isn't a slug
    obj.slug = get_random_string(5) # create one
    slug_is_wrong = True  
    while slug_is_wrong: # keep checking until we have a valid slug
        slug_is_wrong = False
        other_objs_with_slug = type(obj).objects.filter(slug=obj.slug)
        if len(other_objs_with_slug) > 0:
            # if any other objects have current slug
            slug_is_wrong = True
        naughty_words = list_of_swear_words_brand_names_etc
        if obj.slug in naughty_words:
            slug_is_wrong = True
        if slug_is_wrong:
            # create another slug and check it again
            obj.slug = get_random_string(5)

如果覆盖save方法,则每次对象更新slug更改时,如果不希望这样做,则这样做只会在第一次设置slug:

def缓动发生器(): 返回“”。联接(随机.choices(string.ascii_小写+string.digits+string.ascii_大写,k=20))


我会使用散列函数为标题生成散列,并将其用作slug。这不会返回任何错误,并且在我提交表单时,该对象确实成功保存,但当我在管理页面中查看该对象时,它似乎不会生成随机slug。我可能遗漏了什么吗?你能用你的保存方法(确切的内容)显示
models.py的内容吗?缺少
str时出现了一个错误,它可能不起作用。您尚未使用代码。已在编辑2中的模型保存方法中添加。抱歉,我将您的代码放在my views.py而不是models.py中。一旦我把它放到models.py中,当我试图保存表单时,它会给我一个错误。在/dashboard/campaign/new/super()处执行
TypeError至少需要1个参数(给定0)
from django.db import models
from django.utils.crypto import get_random_string
# ...
class SomeModelWithSlug(models.Model):
  slug = models.SlugField(max_length=5,blank=True,) # blank if it needs to be migrated to a model that didn't already have this 
  # ...
  def save(self, *args, **kwargs):
    """ Add Slug creating/checking to save method. """
    slug_save(self) # call slug_save, listed below
    Super(SomeModelWithSlug, self).save(*args, **kwargs)
# ...
def slug_save(obj):
""" A function to generate a 5 character slug and see if it has been used and contains naughty words."""
  if not obj.slug: # if there isn't a slug
    obj.slug = get_random_string(5) # create one
    slug_is_wrong = True  
    while slug_is_wrong: # keep checking until we have a valid slug
        slug_is_wrong = False
        other_objs_with_slug = type(obj).objects.filter(slug=obj.slug)
        if len(other_objs_with_slug) > 0:
            # if any other objects have current slug
            slug_is_wrong = True
        naughty_words = list_of_swear_words_brand_names_etc
        if obj.slug in naughty_words:
            slug_is_wrong = True
        if slug_is_wrong:
            # create another slug and check it again
            obj.slug = get_random_string(5)
def save(self, *args, **kwargs):
    if not self.slug:
        self.slug = slug_generator()
        super(Item, self).save()
    super(Item, self).save()