如何在 Django 中自定义 slug 字段?
Posted
技术标签:
【中文标题】如何在 Django 中自定义 slug 字段?【英文标题】:How do I customize a slug field in Django? 【发布时间】:2015-07-22 00:53:20 【问题描述】:我已经检查了this,但我需要连接两个字段中的内容 好的,问题来了。
我有两个模型,brand
和 product
,看起来像这样:
品牌模型
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。
感谢您的帮助。
【问题讨论】:
【参考方案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()
【讨论】:
我已经为另一个应用安装了它,所以在这里使用它对我来说不是问题,但是,它是可选的。以上是关于如何在 Django 中自定义 slug 字段?的主要内容,如果未能解决你的问题,请参考以下文章