Django get_or_create with icontains

时间:2017-09-08 16:52:19

标签: django

我在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"的内容,我希望获得正确的团队,而不是创建一个大小不正确的重复团队。

3 个答案:

答案 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
    }
)

在“默认值”之外,您应该输入搜索字词。如果对象不存在,则应将创建条件写在“默认值”内