清理数据时附加到ManyToMany表单字段的问题

时间:2011-04-03 04:14:38

标签: django

刚刚从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

2 个答案:

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

Django 1.0 ModelMultipleChoiceField.clean()

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

Django 1.3 ModelMultipleChoiceField.clean()

    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