Django: 'Q' 对象不可迭代
Django: 'Q' object is not iterable
我有以下 APIView:
class SubmitFormAPIView(APIView):
def put(self, request, pk):
# some other codes
form = Form.objects.get(id=pk)
tu_filter, target_user = self._validate_target_user(request, form)
user_status, created = UserFormStatus.objects.get_or_create(
tu_filter,
form_id=pk,
user_id=request.user.pk
)
# Some other codes.
def _validate_target_user(request, form):
if some_conditions:
return Q(), None
else:
try:
target_user_id = int(request.GET.get('target_user_id))
except ValueError:
raise ValidationError()
target_user = get_user_model().objects.get(id=target_user_id)
return Q(target_user_id=target_user_id), target_user
但是当 django 想要执行 get_or_create
方法时,会引发以下错误:
TypeError: 'Q' object is not iterable
注意:如果 _validate_target_user()
returns Q(), None
,则不会出现错误并且视图工作正常。返回 return Q(target_user_id=target_user_id), target_user
时将引发错误。
我知道,问题信息不完整,只是想知道,这个错误可能是什么原因造成的?
除了返回 Q
对象,您还可以只传递一个过滤器字典,例如
{ 'target_user_id': target_user_id }
您可以 运行 以 **tu_filter
作为参数的 get_or_create
,绕过对 Q
.
的需要
class SubmitFormAPIView(APIView):
def put(self, request, pk):
# some other codes
form = Form.objects.get(id=pk)
tu_filter, target_user = self._validate_target_user(request, form)
user_status, created = UserFormStatus.objects.get_or_create(
**tu_filter,
form_id=pk,
user_id=request.user.pk
)
# Some other codes.
def _validate_target_user(request, form):
if some_conditions:
return {}, None
else:
try:
target_user_id = int(request.GET.get('target_user_id))
except ValueError:
raise ValidationError()
target_user = get_user_model().objects.get(id=target_user_id)
return { 'target_user_id': target_user_id }, target_user
编辑:至于导致错误的原因,我的猜测是 Django 不清楚使用 Q
作为 get_or_create 语句的一部分,因为它不知道如何处理它以防需要创建对象。因此,更好的方法是:
UserFormStats.objects.filter(tu_filter).get_or_create(form_id=pk, user_id=request.user.pk)
def get_or_create(self, <b>defaults=None, **kwargs</b>):
这表明 get_or_create(...)
不接受任何 args 不同于 get()
或 filter(...)
方法.
由于您正在执行如下函数,Python 认为 tu_filter
是 default
[=27= 的值] 参数,应该是一个可迭代的参数。
get_or_create(
<b>tu_filter,</b>
form_id=pk,
user_id=request.user.pk
)
我有以下 APIView:
class SubmitFormAPIView(APIView):
def put(self, request, pk):
# some other codes
form = Form.objects.get(id=pk)
tu_filter, target_user = self._validate_target_user(request, form)
user_status, created = UserFormStatus.objects.get_or_create(
tu_filter,
form_id=pk,
user_id=request.user.pk
)
# Some other codes.
def _validate_target_user(request, form):
if some_conditions:
return Q(), None
else:
try:
target_user_id = int(request.GET.get('target_user_id))
except ValueError:
raise ValidationError()
target_user = get_user_model().objects.get(id=target_user_id)
return Q(target_user_id=target_user_id), target_user
但是当 django 想要执行 get_or_create
方法时,会引发以下错误:
TypeError: 'Q' object is not iterable
注意:如果 _validate_target_user()
returns Q(), None
,则不会出现错误并且视图工作正常。返回 return Q(target_user_id=target_user_id), target_user
时将引发错误。
我知道,问题信息不完整,只是想知道,这个错误可能是什么原因造成的?
除了返回 Q
对象,您还可以只传递一个过滤器字典,例如
{ 'target_user_id': target_user_id }
您可以 运行 以 **tu_filter
作为参数的 get_or_create
,绕过对 Q
.
class SubmitFormAPIView(APIView):
def put(self, request, pk):
# some other codes
form = Form.objects.get(id=pk)
tu_filter, target_user = self._validate_target_user(request, form)
user_status, created = UserFormStatus.objects.get_or_create(
**tu_filter,
form_id=pk,
user_id=request.user.pk
)
# Some other codes.
def _validate_target_user(request, form):
if some_conditions:
return {}, None
else:
try:
target_user_id = int(request.GET.get('target_user_id))
except ValueError:
raise ValidationError()
target_user = get_user_model().objects.get(id=target_user_id)
return { 'target_user_id': target_user_id }, target_user
编辑:至于导致错误的原因,我的猜测是 Django 不清楚使用 Q
作为 get_or_create 语句的一部分,因为它不知道如何处理它以防需要创建对象。因此,更好的方法是:
UserFormStats.objects.filter(tu_filter).get_or_create(form_id=pk, user_id=request.user.pk)
这表明def get_or_create(self, <b>defaults=None, **kwargs</b>):
get_or_create(...)
不接受任何 args 不同于 get()
或 filter(...)
方法.
由于您正在执行如下函数,Python 认为 tu_filter
是 default
[=27= 的值] 参数,应该是一个可迭代的参数。
get_or_create(
<b>tu_filter,</b>
form_id=pk,
user_id=request.user.pk
)