【问题标题】:Slugify name field in django formSlugify Django 表单中的名称字段
【发布时间】:2017-03-24 07:49:30
【问题描述】:

我的模型有 Meta: unique_together = ['slug', 'person'], person 是外键字段。在我的表单中,我不想输入 slug 字段。我想从 child_name 字段填充它。我试过了:

class ChildForm(SlugCleanMixin, forms.ModelForm):

    class Meta:
        model = Child
        fields = ('child_name','slug','child_birth_date','blood_group')

        def slug(self):
            return slugify(self.child_name)

但 slug 字段未从 child_name 自动填充。我还尝试在模型中使用 pre_save:

def create_slug(instance, new_slug=None):
    slug = slugify(instance.child_name)
    if new_slug is not None:
        slug = new_slug
    qs = Child.objects.filter(slug=slug).order_by("-id")
    exists = qs.exists()
    if exists:
        new_slug = "%s-%s" %(slug, qs.first().id)
        return create_slug(instance, new_slug=new_slug)
    return slug


def pre_save_post_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = create_slug(instance)

pre_save.connect(pre_save_post_receiver, sender=Child)

但没有什么能达到我的目的。我怎么能那样做?任何帮助将不胜感激。

我的 SlugCleanMixin:

class SlugCleanMixin:
    """Mixin class for slug cleaning method."""

    def clean_slug(self):
        new_slug = (
            self.cleaned_data['slug'].lower())
        if new_slug == 'create':
            raise ValidationError(
                'Slug may not be "create".')
        return new_slug

我的观点:

class ChildrenCreate( ChildrenGetObjectMixin,
    PersonContextMixin, CreateView):
    template_name = 'member/children_form.html'
    model = Child
    form_class = ChildForm


    def get_initial(self):
        person_slug = self.kwargs.get(
            self.person_slug_url_kwarg)
        self.person = get_object_or_404(
            Person, slug__iexact=person_slug)
        initial = {
            self.person_context_object_name:
                self.person,
        }
        initial.update(self.initial)
        return initial

型号:

class Child(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    child_name = models.CharField(max_length=150)
    slug = models.SlugField(max_length=100)
    child_birth_date = models.DateField()
    blood_group = models.CharField(max_length=5, blank=True)

    objects = ChildrenManager()


    class Meta:
        verbose_name_plural = 'children'
        ordering = ['-child_birth_date']
        unique_together = ['slug', 'person']

【问题讨论】:

  • 你能把你SlugCleanMixin课程的内容贴出来吗?
  • 请添加您的模型和视图
  • 你试过通过调试器运行它吗?例如,您根本没有在 create_slug 方法中处理 slug = None 条件
  • 我添加了我的 SlugCleanMixin 并查看了有问题的模型。我没有在调试器中尝试过。
  • github.com/mozilla/unicode-slugify/issues/… 中描述的方法可能对您有用。

标签: django forms slugify


【解决方案1】:

我会尝试查看这个包以生成 slug,因为我已经在多个应用程序中使用过,并且认为它很棒:

https://github.com/un33k/django-uuslug

它们提供了一个简单的使用示例,适用于您的模型将是:

class Child(models.Model):
    child_name = models.CharField(max_length=150)
    slug = models.SlugField(max_length=100)
    ...

    def save(self, *args, **kwargs):
        self.slug = uuslug(self.child_name, instance=self)
        super(Child, self).save(*args, **kwargs)  

【讨论】:

  • 抱歉,您的解决方案不限制同父同子的重复。它产生了同样多的孩子。
【解决方案2】:

首先从表单字段中删除 slug,因为您不需要从用户那里获取。表格将不参与其中。所以你的表格如下:

class ChildForm(SlugCleanMixin, forms.ModelForm):
    class Meta:
        model = Child
        fields = ('child_name','child_birth_date','blood_group')

然后,在您的模型中覆盖保存功能。所以,它变成了这样:

class Child(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    child_name = models.CharField(max_length=150)
    slug = models.SlugField(max_length=100)
    child_birth_date = models.DateField()
    blood_group = models.CharField(max_length=5, blank=True)

    objects = ChildrenManager()

    def save(self):
        if self._created or 'child_name' in self._get_changed_fields():
            self.slug = create_slug(self)


    class Meta:
        verbose_name_plural = 'children'
        ordering = ['-child_birth_date']
        unique_together = ['slug', 'person']

你就完成了。希望这能解决您的问题。

【讨论】:

  • 感谢您在保存方法中的回复,有 self.slug = create_slug(self)。我将使用哪个 create_slug。我应该使用我在问题中发布的 create_slug 方法还是使用 slugify(self.child_name) 代替?
  • 使用 django 提供的标准 slugify 方法,如果多个文档具有相同的 child_name,您的 slug 可能不会保持唯一。我猜你已经尝试在 slug 存在时添加 id(如 1、2、3 等)。因此,如果您计划在 slug 的基础上过滤数据,您的方法会更好。
  • 我使用 javascript 解决了这个问题。我使用 django admin 的 urlify.js 用 child_name 自动 slugify 我的 slug 字段。所有其他选项都会导致唯一性问题。
猜你喜欢
  • 1970-01-01
  • 2012-02-06
  • 2013-09-06
  • 2020-07-31
  • 2018-06-26
  • 2011-06-26
  • 2016-12-24
  • 1970-01-01
  • 2016-06-02
相关资源
最近更新 更多