Django Select2自动补全创建对象报错:'list'无'create'属性
解决DAL Select2QuerySetView创建新对象时的AttributeError问题
这个错误的根源很清晰:你的get_queryset方法在没有查询关键词(self.q为空)时返回了空列表[],而DAL的默认create_object方法会尝试调用self.get_queryset().create(...)——列表对象并没有create方法,所以抛出了AttributeError。
不用修改库源码,有两个更优雅的解决办法:
方法一:在自定义View中重写create_object方法
直接在你的CellLineAutocomplete类里重新定义create_object,绕过get_queryset,直接用模型的管理器来创建对象,这和你修改源码的思路一致,但不会影响库的原始代码:
class CellLineAutocomplete(autocomplete.Select2QuerySetView): create_field = 'cell_line_name' model = CellLine def has_add_permission(self, request): return True def get_queryset(self): if self.q: return CellLine.objects.filter(cell_line_name__icontains=self.q) return [] # 这里保持原样也没关系了 def get_result_label(self, item): return item.cell_line_name # 重写create_object方法 def create_object(self, text): """Create an object given a text.""" return self.model.objects.get_or_create(**{self.create_field: text})[0]
方法二:修改get_queryset返回空QuerySet而非列表
DAL的create_object期望get_queryset返回的是一个QuerySet(哪怕是空的),所以把空列表改成CellLine.objects.none(),这样返回的是EmptyQuerySet,它继承了QuerySet的方法,包括create:
class CellLineAutocomplete(autocomplete.Select2QuerySetView): create_field = 'cell_line_name' model = CellLine def has_add_permission(self, request): return True def get_queryset(self): if self.q: return CellLine.objects.filter(cell_line_name__icontains=self.q) return CellLine.objects.none() # 替换[]为none() def get_result_label(self, item): return item.cell_line_name
这两种方法都能解决问题,推荐第一种,因为它更明确地控制了创建逻辑,不会因为get_queryset的其他修改而受到影响。
内容的提问来源于stack exchange,提问作者T-G
相关产品推荐
相关产品推荐

