刚刚从Django 1.00移动到1.30,我在表单验证过程中突然出错:
AttributeError: 'QuerySet' object has no attribute 'append'
代码如下。在清除表单中用户指定的协调器列表时,我也希望包括所有超级用户。
问题似乎是cleaning_data.get()调用返回一个QuerySet。我以为它返回了一个表示字段类型的对象。正如我上面所说,这段代码曾经用于1.0,但也许这是一个意外。
有人可以告诉我在这种情况下返回的cleaning_data.get以及我如何为其添加其他值?
感谢。
class Party(models.Model):
coordinators = models.ManyToManyField( 'PersonProfile', blank=True, related_name='event_coordinator_set', help_text='' )
class PartyForm(ModelForm):
class Meta:
model = Party
def __init__( self, *args, **kwargs ):
super( PartyForm, self ).__init__(*args, **kwargs)
self.fields['coordinators'].queryset = PersonProfile.objects.exclude( user__is_superuser=1 )
def clean_coordinators( self ):
coordinators = self.cleaned_data.get( 'coordinators', '' )
superuser_list = PersonProfile.objects.filter( user__is_superuser=1 )
for superuser in superuser_list:
coordinators.append( superuser )
return coordinators
答案 0 :(得分:3)
尝试以下方法:
from django.db.models import Q
def clean_coordinators( self ):
coordinators = self.cleaned_data.get( 'coordinators', '' )
if coordinators:
return PersonProfile.objects.filter(
Q(pk__in=coordinators) | Q(user__is_superuser=1)
)
else:
return PersonProfile.objects.filter(user__is_superuser=1)
答案 1 :(得分:3)
一旦您发现它是QuerySet
,您就可以将查询集转换为列表并保留其余代码完整... coordinatiors = list(myqueryset)
,但我会推荐Thierry的溶液
Anyho,你是对的:我看了django 1.0,而ModelMultipleChoiceField
曾经用来返回一个列表。现在,它返回QuerySet
。
final_values = []
for val in value:
try:
obj = self.queryset.get(pk=val)
except self.queryset.model.DoesNotExist:
raise ValidationError(self.error_messages['invalid_choice'] % val)
else:
final_values.append(obj)
return final_values
for pk in value:
try:
self.queryset.filter(**{key: pk})
except ValueError:
raise ValidationError(self.error_messages['invalid_pk_value'] % pk)
qs = self.queryset.filter(**{'%s__in' % key: value})
pks = set([force_unicode(getattr(o, key)) for o in qs])
for val in value:
if force_unicode(val) not in pks:
raise ValidationError(self.error_messages['invalid_choice'] % val)
# Since this overrides the inherited ModelChoiceField.clean
# we run custom validators here
self.run_validators(value)
return qs