我正在使用SeparatedValuesField来跟踪字符串列表,如http://davidcramer.posterous.com/code/181/custom-fields-in-django.html所述,以及SO上的很多帖子都建议将其作为存储字符串列表的正确方法。
class UserProfile(models.Model):
user = models.OneToOneField(User)
device_ids = SeparatedValuesField(blank=True, null=True, default=[])
它在我的应用程序中工作正常,我可以添加设备ID并在管理界面中按预期查看它们。
user_profile.device_ids = ['666666-D849-524F-6984-7E9B2D768546']
但问题在于管理界面,当我打开UserProfile对象的详细信息页面时,管理界面本身正在为我的device_ids字段添加额外的值。
例如,我的应用程序在字段中插入一个值,当我在管理界面中查看它时,它看起来像这样:
[u'666666-D849-524F-6984-7E9B2D768546']
然后我在我的UserProfile对象上更改了一些其他随机属性,并使用内置的django管理界面保存按钮保存它。
当我再次为我的对象打开UserProfile对象详细信息页面时,该值现在如下所示:
[u"[u'666666-D849-524F-6984-7E9B2D768546']"]
如果我重复这个只是点击保存然后打开这个详细页面的过程,它将继续用u“[]字符嵌套实际值。
我可以做些什么来改变这个功能吗?我应该以不同的方式存储字符串列表吗?
答案 0 :(得分:1)
我遇到了同样的问题,最后由于这两个different answers而想出来了。
在这种情况下,您需要的是一个自定义窗口小部件,它将字符串列表呈现为字符串。此小部件需要绑定到自定义字段:
class FlattenListWidget(forms.TextInput):
def render(self, name, value, attrs=None):
if not value is None:
value = ','.join(str(v) for v in value)
return super(FlattenListWidget, self).render(name, value, attrs)
class UserProfileAdminForm(forms.ModelForm):
class Meta:
model = UserModel
widgets = {
'device_ids': FlattenListWidget(),
}
class UserProfileAdmin(admin.ModelAdmin):
form = UserProfileAdminForm
希望有效。我的代码中有不同的模型名称,但设法从我的自定义字段中获取包含逗号分隔值列表的文本输入。
如果您想使用逗号和空格value = ', '.join(str(v) for v in value)
加入字符串,请记住strip()
自定义字段get_db_prep_value
方法中的值。否则,空格将被保存回数据库。
要使用list_display
中的自定义字段,您可以向管理模型添加自定义字段:
class UserProfileAdmin(admin.ModelAdmin):
form = UserProfileAdminForm
list_display = ('ids_list',)
def ids_list(self, obj):
if obj.device_ids:
return ', '.join(str(i) for i in obj.device_ids)
return None
答案 1 :(得分:1)
Oiva Eskola的答案看起来很好(尽管没有试过)。
在这个问题之前找到Django源代码,我也偶然发现了以下内容(有效):
SeparatedValuesField(models.TextField):
# ...
def value_from_object(self, obj):
return self.get_db_prep_value(super(SeparatedValuesField, self).value_from_object(obj))