我在icontains
电话中使用get_or_create
收到了意外结果。
采用以下示例:
>>>team_name = "Bears"
>>>Team.objects.get(name__icontains=team_name) # returns DoesNotExist as expected
>>>team, created = Team.objects.get_or_create(name__icontains=team_name)
>>>print(created) # Prints True as expected
>>>print(team.name) # Prints an empty string!
为什么这会创建一个名称空白而不是“熊”的团队?我在这里使用get_or_create
的原因是,如果后续用户发布了类似"BearS"
的内容,我希望获得正确的团队,而不是创建一个大小不正确的重复团队。
答案 0 :(得分:2)
我认为您应该将get()
和create()
功能分开,而不是使用get_or_create()
,因为__icontains
查找仅适用于get()
。
尝试做这样的事情:
>>> team_name = 'Bears'
>>> teams = Team.objects.filter(name__icontains=team_name)
# This will filter the teams with this name
>>> team = teams.first() if teams.exists() else Team.objects.create(name=team_name)
# Now your team is the first element of your previous query (it returns a QuerySet with single element) if it exists
# Otherwise, you create a new Team.
答案 1 :(得分:2)
除了wencakisa的答案之外,另一个选择是在defaults
中包含get_or_create
参数,因为Django剥离了包含__
分隔符的查找。查看this question的答案。
代码如下:
Team.objects.get_or_create(
name__icontains=team_name,
defaults = {
"name": team_name
}
)
答案 2 :(得分:0)
正确的方法是使用Django函数get_or_create()。但是,除非要精确匹配,否则应使用“ iexact”()而不是“ contains”,在这种情况下,应仅使用“ exact”:
Team.objects.get_or_create(
name__iexact=team_name,
defaults = {
"name": team_name
}
)
在“默认值”之外,您应该输入搜索字词。如果对象不存在,则应将创建条件写在“默认值”内