سلام استاد
سال نوتون مبارک ، انشالله که سال خیلی خوبی همراه با سلامتی و آرامش داشته باشید
راجب جلسه ۸۳ یه سوال داشتم
من یه فرم ثبت نام دارم
Forms.py
class RegisterForm(forms.Form):
username = forms.CharField(
label="",
widget= forms.TextInput(
attrs = {"placeholder":"نام کاربری" , "title":"نام کاربری"}
),
error_messages= {
"required" : "لطفا نام کاربری خود را وارد کنید",
},
validators=[MinLengthValidator(4, "حداقل باید ۴ کاراکتر برای نام کاربری وارد کنید"),
MaxLengthValidator(20, "حداکثر میتوانید ۲۰ کاراکتر برای نام کاربری وارد کنید")
]
)
email = forms.EmailField(
label="",
widget= forms.EmailInput(
attrs = {"placeholder":"ایمیل" , "title":"ایمیل"}
),
error_messages= {
"required" : "لطفا ایمیل خود را وارد کنید"
},
validators=[MaxLengthValidator(300, "نهایتا برای رمز عبور میتونی ۳۰۰ کاراکتر وارد کنی!"),
MinLengthValidator(5, "حداقل باید ۵ کاراکتر برای نام کاربری وارد کنید.")
]
)
password = forms.CharField(
label="",
widget= forms.PasswordInput(
attrs = {"placeholder":"رمز عبور" , "title":"رمز عبور"}
),
error_messages= {
"required" : "لطفا رمز عبور خود را وارد کنید"},
validators=[MaxLengthValidator(128, "دیگه تهش میتونی ۱۲۸ کاراکتر برای رمز عبور وارد کنی!"),
MinLengthValidator(8, "حداقل ۸ کاراکتر برای رمز عبور میخوای!")
]
)
#######################################################################
confirm_password = forms.CharField(
label="",
widget= forms.PasswordInput(
attrs = {"placeholder":"تکرار رمز عبور" , "title":"رمز عبور"}
),
error_messages= {
"required" : "لطفا تکرار رمز عبور خود را وارد کنید"
}
)
def clean_username(self):
username = self.cleaned_data.get('username')
username_exists = User.objects.filter(username=username).exists()
if username_exists:
raise forms.ValidationError("این نام کاربری قبلا ثبت شده \n میتوانید لاگین کنید")
if username.isdigit():
raise forms.ValidationError("نام کاربری نمیتونه فقط از عدد باشه!")
return username
def clean_email(self):
email = self.cleaned_data.get('email')
email_exists = User.objects.filter(email=email).exists()
if email_exists:
raise forms.ValidationError("ایمیل شما قبلا ثبت شده است\n در صورت نیاز میتوانید لاگین کنید")
return email
def clean_password(self):
password = self.cleaned_data['password']
print(self.cleaned_data)
confirm_password = self.cleaned_data.get('confirm_password')
if password != confirm_password :
raise forms.ValidationError("تکرار کلمه عبور با کلمه عبور مطابق نیست!")
return password
Views.py
class RegisterView(View):
def get(self, request):
if request.user.is_authenticated:
username = request.user.username
return render(request, "login_success.html", {"username":username})
else:
form = RegisterForm()
return render(request, "register.html", {"form":form})
def post(self, request):
form = RegisterForm(data=request.POST)
if form.is_valid():
# Add user to temp user
username = form.cleaned_data["username"]
password = make_password(form.cleaned_data["password"])
email = form.cleaned_data['email']
token = random_string(50)
TempUser.objects.create(username=username,
password=password,
email=email,
token=token
)
# Send varify mail
verification_url = reverse_lazy("account_verify_page", args=[token])
email_body = render_to_string("email_body.html", {
"url":verification_url
})
msg = EmailMessage(
"تایید حساب",
email_body,
"atanabain@gmail.com",
[email]
)
msg.content_subtype = "html"
msg.send()
messages.success(request, "ایمیل فعالسازی برای شما ارسال شد")
return redirect(reverse_lazy("login_page"))
else:
return render(request, "register.html", {"form":form})
مشکل اینجاست من هر کاری میکنم به من ارر یکسان نبودن رمز و تکرارش رو میده ، وقتی مقدار cleaneddata رو پرینت کردم دیدم password هست ولی confirm_password نیستش
در نتیجه مقدار None به جای confirm_password قرار میگیره و ارر میده
ممنون میشم راهنمایی کنید
سلام خدمت شما دوست عزیز
ببینین برای چک کردن مقدار password و confirm_password باید کدهای چک کردن رو داخل متد clean_confirm_password بنویسین دوست من
علت اینه که زمانی که متد clean_password داره اجرا میشه، هنوز متد clean_confirm_password فراخوانی نشده و به همین دلیل مقدارش در cleaned_data نیست
دو روش برای حل این مشکل وجود داره
یا کدهای مربوط به چک کردن برابر بودن کلمه های عبور رو در متد clean_confirm_password قرار بدین
یا به جای استفاده از self.cleaned_data از self.data استفاده کنین
ممنون از پاسخگوییتون
یه موضوعی برام پیش اومد
من همین سوالو از چت جی پی تی پرسیدم درست حسابی جواب نداد ولی یه موضوعی مطرح کرد ، که جنگو اول به سراغ ولیدیشن های دیفالت میره بعد متود های clean برای هر فیلد و بعدش به سراغ متود clean کلی فرم
خب با این حساب من انتظار دارم ولیدیشن ویفالت فیلد password روی confirm password اعمال بشه و توی cleaned data باشه
چرا این اتفاق نمیفته؟
ببینین این فرآیند به ترتیب انجام میشه دوست من
یعنی ترتیب فیلدهایی که تعریف کردین اهمیت داره
به عنوان مثال، اگر شما درون فرم ، ابتدا confirm_password رو تعریف کنین و بعد password رو ، اونوقت میبینین که درون cleaned_data مقدار password هم میاد
نکته ی بعدی اینه که تا زمانی که متد clean برای فیلدها اجرا نشه، مقدارش توی cleaned_data ذخیره نمیشه دوست من
آهان متوجه شدم
پس اگه درست فهمیده باشم باید توی فیلد آخرم که کانفرم پسورد هست بزارم تا قبلش مقدار فیلد قبلی باشه
ممنون از راهنماییتون
وقتتون بخیر
بله دوست من
دستور چک کردن کلمه های عبور رو درون clean_confirm_password قرار بدین تا همه مقادیر نمایش داده بشن