Je voudrais de l'aide ou des conseils sur la façon de tester les erreurs dans l'un de mes formulaires Django. Il est responsable de s'assurer que l'utilisateur entre un ID de session valide qui est utilisé comme un jeton d'authentification pour une API tierce. Les ID valides ont 32 caractères et sont alphanumériques.Pourquoi Django AssertFormError lance-t-il un TypeError: l'argument de type 'property' n'est pas itérable?
J'ai choisi une approche qui valide le champ, plutôt que le modèle.
Lorsque je le teste manuellement à l'aide du serveur de développement, cela fonctionne comme prévu. C'EST À DIRE. Si l'utilisateur colle une chaîne de la mauvaise longueur ou avec les caractères spéciaux, la méthode de validation du champ crée des erreurs qui sont ensuite affichées via une boucle for autour des erreurs de formulaire dans le modèle html.
Je ne comprends pas l'erreur suivante. J'ai temporairement modifié testcases.py pour prouver que les erreurs lui ont été transmises - alors pourquoi context [form] .errors est-il une 'propriété' et comment est-il arrivé?
J'utilise Django 1.10 et Python 3.5.1
======================================================================
ERROR: test_index_sessid_short_strings (poe.tests.TestBannerButtons)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/adam.green/Documents/workspace/poe-client/poetools_project/poe/tests.py", line 105, in test_index_sessid_short_strings
self.assertFormError(response, 'form', "new_sessid" , 'The Session ID needs to be exactly 32 characters long')
File "/Users/adam.green/.virtualenvs/poe-tools/lib/python3.5/site-packages/django/test/testcases.py", line 421, in assertFormError
if field in context[form].errors:
TypeError: argument of type 'property' is not iterable
----------------------------------------------------------------------
Ran 1 test in 0.805s
Test
def test_index_sessid_short_strings(self):
url = reverse('index')
response = self.client.post(url, {'new_sessid': "f14"})
self.assertFormError(response, 'form', "new_sessid" , 'The Session ID needs to be exactly 32 characters long')
form.py
class SessID(forms.Field):
def validate(self, session_id):
"""Check if value consists only of valid emails."""
# Use the parent's handling of required fields, etc.
super().validate(session_id)
if len(session_id) <32> len(session_id):
raise ValidationError(
_('The Session ID needs to be exactly 32 characters long'),
code = 'sessid wrong length'
)
if not re.match("^[A-Za-z0-9]*$", session_id):
raise ValidationError(
_('The Session ID should only have letters and numbers, no special characters'),
code = 'sessid not alphanumeric'
)
class ResetSessID(forms.ModelForm):
new_sessid = SessID()
#forms.CharField(widget=forms.TextInput(attrs={'class':'special', 'size': '32'}) )
def __init__(self, *args, **kwargs):
super(ResetSessID, self).__init__(*args, **kwargs)
stdlogger.info("init of ResetSessID")
#print("dir")#, self.fields.items['new_sessid'])
if kwargs.get('instance'):
new_sessid = kwargs['instance'].new_essid
stdlogger.info("inner kwargs loop")
return super(ResetSessID, self).__init__(*args, **kwargs)
class Meta:
model = PoeAccount
exclude = ("acc_name", "sessid")
def clean(self):
if 'reg_button' in self.data:
print("amazing")
views.py
def index(request):
request.session.set_test_cookie()
item_category_list = ItemCategory.objects.all()
modifications_list = FixCategory.objects.all()
context_dict = {}
if request.user.is_authenticated:
if request.method == 'POST':
form = ResetSessID(request.POST)
if form.is_valid():
# get the right account
me = poe.models.PoeAccount.objects.get(
acc_name = request.user.poeuser.poe_account_name
)
# commit new sessid passed to here
# me.full_clean()
me.sessid = form['new_sessid'].value()
me.save(update_fields=['sessid'])
context_dict["old_sessid"] = me.sessid
context_dict['form'] = ResetSessID
response = render(request,'poe/index.html', context_dict)
#return response
else:
context_dict['errors'] = form.errors
print("form has errors", form.errors)
me = poe.models.PoeAccount.objects.get(
acc_name = request.user.poeuser.poe_account_name
)
context_dict['errors'] = form.errors
context_dict["old_sessid"] = me.sessid
context_dict['form'] = ResetSessID
for x, y in form.errors.items():
print("errors", x, y)
response = render(request,'poe/index.html', context_dict)
#return response
else:
context_dict = {'form': ResetSessID}
me = poe.models.PoeAccount.objects.get(acc_name = request.user.poeuser.poe_account_name)
context_dict["old_sessid"] = me.sessid
context_dict.update({'item_categories': item_category_list, 'mods': modifications_list})
# make sure the session keeps track of the number of visits
visits = request.session.get('visits')
if not visits:
visits = 1
reset_last_visit_time = False
last_visit = request.session.get('last_visit')
if last_visit:
last_visit_time = datetime.datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S")
if (datetime.datetime.now() - last_visit_time).seconds > 0:
# ...reassign the value of the cookie to +1 of what it was before...
visits = visits + 1
# ...and update the last visit cookie, too.
reset_last_visit_time = True
else:
# Cookie last_visit doesn't exist, so create it to the current date/time.
reset_last_visit_time = True
# make sure the session keeps track of time last visited
if reset_last_visit_time:
request.session['last_visit'] = str(datetime.datetime.now())
request.session['visits'] = visits
context_dict['visits'] = visits
#print("context_dict", context_dict)
response = render(request,'poe/index.html', context_dict)
return response
génial, merci beaucoup - qui l'a réparé immédiatement. – Flicky