【问题标题】:How do I customize a slug field in Django?如何在 Django 中自定义 slug 字段?
【发布时间】:2015-07-22 00:53:20
【问题描述】:

我已经检查了this,但我需要连接两个字段中的内容 好的,问题来了。

我有两个模型,brandproduct,看起来像这样:

品牌模型

class Brand(models.Model):
    name = models.CharField(max_length=29)
    website = models.URLField()

    def __unicode__(self):
        return self.name

产品型号

class Product(models.Model):
    brand = models.ForeignKey(Brand)
    name = models.CharField(max_length=140)
    slug = models.SlugField()

    def __unicode__(self):
        return self.name

管理方法

from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}

模型输入示例:

**Brand**
Name: Example
Website: http://www.example.com

**Product**
Brand: Example (Selection)
Name: Product
Slug: product(prepopulated)

我希望 slug 是 example-product 而不是 product。如何将品牌和名称连接为 slug。

感谢您的帮助。

【问题讨论】:

    标签: python django django-models django-admin


    【解决方案1】:

    将品牌添加到 prepopulated_fields 字典仅返回 id 而不是 str/unicode 值。

    class ProductAdmin(admin.ModelAdmin):
        prepopulated_fields = {'slug': ('brand', 'name',)}
    

    一种方法是添加 save_model 方法 ModelAdmin

    from django.utils.text import slugify
    
    class ProductAdmin(admin.ModelAdmin):    
        def save_model(self, request, obj, form, change):
            # don't overwrite manually set slug
            if form.cleaned_data['slug'] == "":
                obj.slug = slugify(form.cleaned_data['brand']) + "-" + slugify(form.cleaned_data['name'])
            obj.save()
    

    【讨论】:

      【解决方案2】:

      你不能。根据 Django 文档:

      prepopulated_fields 不接受 DateTimeField、ForeignKey 或 ManyToManyField 字段。

      链接:https://docs.djangoproject.com/en/1.8/ref/contrib/admin/

      我试过了:

      prepopulated_fields = {'slug': ('brand', 'name')}
      

      这将在品牌 ID 后附加名称而不是品牌名称,因此您会得到 '1-product' 而不是 'example-product'


      更新:将 slug 字段保存到数据库和在管理页面中显示 slug 字段是两件不同的事情。保存会将字符串保存到数据库中。但 'prepopulated_fields' 仅用于展示。它只会影响管理页面的外观。

      【讨论】:

      • 但是必须有某种方法,使用保存功能插入带有连接字符串的 slug 字段,无论如何? (def save(self, *args, **kwargs):) ??
      • @John prepopulated_fields 的工作方式由一个名为 prepopulate.js 的 javascript 文件定义。它只是拉取存储在品牌下拉列表选项标签的 value 属性中的值并将其放入 slug 文本框中。它与将记录保存到数据库中的save() 方法无关。它们是两种不同的东西。
      • 我的意思是用 js 替换 slugbox 上的 'dummy slug',就在模型对象被保存之前,你知道 js 或 vbs 甚至 python 可以处理代码但只有在 @987654325 时才保存@方法被调用,我要求修改保存方法好,我们关心数据库不太关心管理员。 ;)
      • @John 真的很难理解你在问什么。如果下面的答案回答了您的问题,那就太好了。但奇怪的是,下面答案中包含的信息已经在您原始帖子的链接中。此外,您的prepopulated_fields = {'slug': ('name',)} 行完全误导了您真正要问的内容。无论如何,下次问一个更简洁的问题。
      【解决方案3】:

      您可以在产品保存中添加一个 slugify 功能(免责声明:我没有尝试使用外键执行此操作,所以我不是 100% 确定,但此方法对我有效,如果有效,请告诉我给你)。

      from unidecode import unidecode
      from django.template.defaultfilters import slugify    
      
      class Product(models.Model):
      ...
      
          def save(self):
              if not self.id: # if this is a new item
                  newslug = '{0} {1}'.format(self.brand__name, self.name)  
                  self.slug = slugify(unidecode(newslug))
              super(Product, self).save()
      

      【讨论】:

      • 我已经为另一个应用安装了它,所以在这里使用它对我来说不是问题,但是,它是可选的。
      猜你喜欢
      • 1970-01-01
      • 2016-12-22
      • 2021-08-19
      • 2020-08-09
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 2015-05-11
      • 2014-04-21
      相关资源
      最近更新 更多