نموذج بسيط لا يتحقق
-
02-10-2019 - |
سؤال
لقد وجدت هنا على Stackoverflow طريقة لتوسيع المصادقة المدمجة في Django باستخدام الإشارات. يتم تعريف المستخدم الأساسي الخاص بي بواسطة "البريد الإلكتروني" وكلمات المرور (لذلك لا اسم مستخدم هناك). لذلك أحاول تعديله لاحتياجاتي ، لكنني أحصل على خطأ في التحقق من صحة النموذج الخاص بي. الشيء الغريب هو أن الخطأ متصل بحقل user.email وأنا "مستخدم بالفعل" على الرغم من أنني فقط أسجل في الوقت الحالي. هل تحاول حفظه مرتين أم ماذا؟ لقد اكتشفت ذلك عندما كنت أرسل قاموسًا مع البيانات إلى Contstructor في Shell: form = MyForm(data={})
. بعد هذا النموذج ، كان لا يزال غير صالح ، لكن تغيير البريد الإلكتروني إلى قيمة مختلفة أعطاني أخيرًا.
وظيفة user_created متصلة بإشارة التسجيل:
def user_created(sender, user, request, **kwargs):
form = CustomRegistrationForm(request.POST, request.FILES)
if form.is_valid():
data = UserProfile(user=user)
data.is_active = False
data.first_name = form.cleaned_data['first_name']
data.last_name = form.cleaned_data['last_name']
data.street = form.cleaned_data['street']
data.city = form.cleaned_data['city']
data.save()
else:
return render_to_response('user/data_operations/error.html', {'errors': form._errors}, context_instance=RequestContext(request))
user_registered.connect(user_created)
شكلي:
class CustomRegistrationForm(RegistrationForm):
first_name = forms.CharField(widget=forms.TextInput(attrs=attrs_dict), max_length=50)
last_name = forms.CharField(widget=forms.TextInput(attrs=attrs_dict), max_length=50)
street = forms.CharField(widget=forms.TextInput(attrs=attrs_dict), max_length=50)
city = forms.CharField(widget=forms.TextInput(attrs=attrs_dict), max_length=50)
مثالي :
class UserProfile(models.Model):
first_name = models.CharField(_("Name"), max_length=50, blank=False,)
last_name = models.CharField(_("Last name"), max_length=50, blank=False,)
street = models.CharField(_("Street"), max_length=50, blank=False,)
city = models.CharField(_("City"), max_length=50, blank=False,)
user = models.ForeignKey(User, unique=True, related_name='profile',)
نموذج التسجيل: تسجيل الفصل (Forms.form):
email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
maxlength=75)),
label=_("Adres email"))
password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
label=_("Haslo"))
password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
label=_("Haslo powtorzone"))
def clean_email(self):
email = self.cleaned_data.get("email")
if email and User.objects.filter(email=email).count() > 0:
raise forms.ValidationError(
_(u"Already in use."))
return email
المحلول
يتم إرسال إشارة "user_registered" بعد حفظ المستخدم. لذلك يحتوي بالفعل على حقل "بريد إلكتروني" محدد.
تحديث
باستخدام تفكير مضطرب:
form = CustomRegistrationForm(request.POST, request.FILES, notvalidateemail=True)
وفي الشكل:
def __init__(self, *args, **kwargs):
self.notvalidateemail = kwargs.pop('notvalidateemail',False)
super(CustomRegistrationForm, self).__init__(*args, **kwargs)
def clean_email(self):
if self.notvalidateemail:
return
else:
#your cleaning here
return email
نصائح أخرى
مشكلة:
يتم حفظ النموذج الخاص بك أولاً بواسطة Django-Registration. ثم يمكنك حفظه مرة أخرى في user_created.
حلول:
استخدم نموذجًا مختلفًا في user_created. واحدة لن يكون قد تم حفظ الحقول بالفعل (هذه من نموذج المستخدم مثل البريد الإلكتروني). تريد فقط حفظ بيانات إضافية في user_created ، أليس كذلك؟
أضف بعض المعلمات إلى النموذج مثل:
في user_created:
form = CustomRegistrationForm(dontvalidateemail=True, request.POST, request.FILES)
وفي الشكل فيه;
self.dontvalidateemail = dontvalidateemail
ثم فقط تحقق من ذلك في clean_email.