AttributeError / object没有属性'cleaning_data'

时间:2021-09-16 16:41:58

I'm trying to make a formsets with 2 fields, first for a text, second with choicefield. I have got error like in topic and don't know how to replace "cleaned_data". The error comes when i push data by POST.

我正在尝试制作一个包含2个字段的表单集,第一个用于文本,第二个用于选择字段。我在主题中遇到错误,不知道如何替换“cleaning_data”。当我通过POST推送数据时出现错误。

The error comes in: " proficiency = x.cleaned_data.get('proficiency') " in the views.

错误在于:视图中的“熟练度= x.cleaned_data.get('熟练度')”。

Here's my code:

这是我的代码:

views.py:

@login_required
def skill_settings(request):
"""
Allows a user to update their own profile.
"""
userrr = request.user

#has_skills = Skill.objects.count() > 0

SkillFormSet = formset_factory(SkillForm, formset=BaseSkillFormSet)

user_skills = UserSkill.objects.filter(user=request.user).order_by('skill__name')
skill_data = [{'skill': s.skill, 'proficiency': s.proficiency}
            for s in user_skills]

LinkFormSet = formset_factory(LinkForm, formset=BaseLinkFormSet)

user_links = SkillMod.objects.filter(userrr=userrr)
link_data = [{'skil': l.skil}
            for l in user_links]

if request.method == 'POST':
    skill_formset = SkillFormSet(request.POST, prefix='skill')
    link_formset = LinkFormSet(request.POST, prefix='link')

    forms = [link_formset, skill_formset]



    if link_formset.is_valid():

        objj = []
        objj2 = []


        for link_form in link_formset:
            skil = link_form.cleaned_data.get('skil')

            objj.append(SkillMod(userrr=userrr, skil=skil))

        for x in skill_formset:
            proficiency = x.cleaned_data.get('proficiency')

            objj2.append(UserSkill(user=request.user, proficiency=proficiency))


        try:
            with transaction.atomic():
                SkillMod.objects.filter(userrr=userrr).delete()
                SkillMod.objects.bulk_create(objj)

                UserSkill.objects.filter(user=request.user).delete()
                UserSkill.objects.bulk_create(objj2)

                messages.success(request, 'You have updated your profile.')

        except IntegrityError:
            messages.error(request, 'There was an error.')
            return redirect(reverse('skill_settings'))

else:
    skill_formset = SkillFormSet(initial=skill_data, prefix='skill')
    link_formset = LinkFormSet(initial=link_data, prefix='link')


context = {
    'skill_formset': skill_formset,
    'link_formset': link_formset,
    #'has_skills': has_skills,
}

return render(request, 'skill_settings.html', context)

models.py:

class Skill(models.Model):
"""
Represents a skill in the community.
"""
name = models.CharField(('name'), max_length=100, unique=True)
owner = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                through='UserSkill',
                                verbose_name=('owner'))

class Meta:
    verbose_name = ('skill')
    verbose_name_plural = ('skills')

def __str__(self):
    return self.name


class UserSkill(models.Model):
"""
How proficient an individual user is at a particular skill.
This model joins User and Skill ('through' table).
"""
BEGINNER = 10
INTERMEDIATE = 20
ADVANCED = 30
EXPERT = 40

PROFICIENCY_CHOICES = (
    ('', '---------'),
    (BEGINNER, ('Beginner')),
    (INTERMEDIATE, ('Intermediate')),
    (ADVANCED, ('Advanced')),
    (EXPERT, ('Expert')),
)

user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=("user"))
skill = models.ForeignKey(Skill, verbose_name=('skill'))
proficiency = models.IntegerField(('proficiency'),
                                choices=PROFICIENCY_CHOICES,
                                default=BEGINNER)

def get_proficiency_percentage(self):
    """
    Return a user's profiency in a particular skill as a percentage,
    based on the position of the proficiency in PROFICIENCY_CHOICES.
    """
    choice_values = [choice[0] for choice in self.PROFICIENCY_CHOICES]
    if '' in choice_values:
        choice_values.remove('')  # Remove the empty proficiency choice
    choice_values.sort()  # Ensure values are in the correct order

    value = choice_values.index(self.proficiency) + 1
    factor = 100 / len(choice_values)
    percentage = round(value * factor)

    return percentage

class Meta:
    verbose_name = ('user skill')
    verbose_name_plural = ('user skills')
    unique_together = ('user', 'skill')

def __str__(self):
    return '{} - {}'.format(self.user.get_full_name(), self.skill.name)







class SkillMod(models.Model):

userrr = models.ForeignKey(settings.AUTH_USER_MODEL,
                        verbose_name=('userrr'),
                        related_name='linksss')

skil = models.CharField(max_length=50)

def __str__(self):
    return self.skil

def save(self, *args, **kwargs):
    """
    Attempt to match a user link to a recognised brand (LinkBrand).
    """
    super(SkillMod, self).save(*args, **kwargs)

forms.py:

class SkillForm(forms.Form):
"""
Form for individual user skills
"""
skills = Skill.objects.all()
skill = forms.ModelChoiceField(queryset=skills, required=False)

proficiency = forms.ChoiceField(choices=UserSkill.PROFICIENCY_CHOICES,
                                required=False)


class LinkForm(forms.Form):
skil = forms.CharField(
    max_length= 50,
    widget = forms.TextInput(attrs = {'placeholder': 'Skill',}), required = False)

skill_settings.html:

{% block profile %}
<p></p>
<div class="jumbotron">
    {% if messages %}
        {% for message in messages %}
            <p>{{ message }}</p>
        {% endfor %}
    {% endif %}

    <form method="post">
        {% csrf_token %}

                    {{ link_formset.management_form }}
                    {{ skill_formset.management_form }}
                    {{ form.management_form }}

                     <div class="link-formset">
                        <div style="border-style:groove; border-radius: 8px; padding: 12px 0 0 7px;"> 
                    {% for link_form in link_formset %}

                        <p style="font-size:15px">Firma: 
                        {{ link_form.skil }}
                        {% if link_form.skil.errors %}
                            {% for error in link_form.skil.errors %}
                                {{ error|escape }}
                            {% endfor %}
                        {% endif %}</p>

                    {% endfor %}



                    {% for form in skill_formset %}

                        {{ form.proficiency }}

                    {% endfor %}

                        </div>
                    </div>


                    {% if skill_formset.non_form_errors %}
                        <div>
                            <span class="form-error">
                                {% for error in skill_formset.non_form_errors %}
                                    <span><i class="fa fa-exclamation-triangle"></i>{{ error|escape }}</span>
                                {% endfor %}
                            </span>
                        </div>
                    {% endif %}



        {% if link_formset.non_form_errors %}
            {% for error in link_formset.non_form_errors %}
                {{ error|escape }}
            {% endfor %}
        {% endif %}

        <input type="submit" value="Update Profile" class="button"/>
    </form>

    <!-- Include formset plugin - including jQuery dependency -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="{% static 'js/jquery.formset.js' %}"></script>
        <script>
            $('.link-formset').formset({
                addText: 'add next',
                deleteText: 'remove'
            });
        </script>

</div>
{% endblock %}

1 个解决方案

#1


0  

cleaned_data is only available after the form have been validated with is_valid(). You're currently only validating link_formset but then trying to access cleaned_data for x in skill_formset, which is not yet created.

cleaning_data仅在使用is_valid()验证表单后才可用。您目前只验证link_formset,然后尝试访问尚未创建的skill_formset中的x的cleaning_data。

Read more about it here: https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.cleaned_data

在这里阅读更多相关信息:https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.cleaned_data

#1


0  

cleaned_data is only available after the form have been validated with is_valid(). You're currently only validating link_formset but then trying to access cleaned_data for x in skill_formset, which is not yet created.

cleaning_data仅在使用is_valid()验证表单后才可用。您目前只验证link_formset,然后尝试访问尚未创建的skill_formset中的x的cleaning_data。

Read more about it here: https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.cleaned_data

在这里阅读更多相关信息:https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.cleaned_data