from django import forms from django.contrib.auth.models import User from .models import Student, Subject, Classroom, City, Governorate class StudentRegistrationForm(forms.ModelForm): full_name = forms.CharField(max_length=150, required=True, label="Full Name") username = forms.CharField(max_length=150, required=True) email = forms.EmailField(required=True) password = forms.CharField(widget=forms.PasswordInput, required=True) password_confirm = forms.CharField(widget=forms.PasswordInput, required=True, label="Confirm Password") classroom = forms.ModelChoiceField(queryset=Classroom.objects.all(), required=True, empty_label="Select Classroom") subjects = forms.ModelMultipleChoiceField( queryset=Subject.objects.all(), required=False, widget=forms.CheckboxSelectMultiple, label="Select Subjects" ) class Meta: model = Student fields = ['mobile_number', 'governorate', 'city', 'avatar'] widgets = { 'avatar': forms.FileInput(attrs={'accept': 'image/*', 'capture': 'camera'}), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Add Bootstrap classes for field_name, field in self.fields.items(): if field.widget.__class__.__name__ == 'CheckboxInput': field.widget.attrs['class'] = 'form-check-input' elif field.widget.__class__.__name__ != 'CheckboxSelectMultiple': field.widget.attrs['class'] = 'form-control' field.widget.attrs['placeholder'] = field.label # Important for Floating Labels! # optimize subjects loading self.fields['subjects'].queryset = Subject.objects.none() if 'classroom' in self.data: try: classroom_id = int(self.data.get('classroom')) self.fields['subjects'].queryset = Subject.objects.filter(classroom_id=classroom_id) except (ValueError, TypeError): pass elif self.instance.pk and self.instance.classroom: self.fields['subjects'].queryset = Subject.objects.filter(classroom=self.instance.classroom) # optimize city loading self.fields['city'].queryset = City.objects.none() if 'governorate' in self.data: try: governorate_id = int(self.data.get('governorate')) self.fields['city'].queryset = City.objects.filter(governorate_id=governorate_id) except (ValueError, TypeError): pass elif self.instance.pk and self.instance.governorate: self.fields['city'].queryset = City.objects.filter(governorate=self.instance.governorate) def clean(self): cleaned_data = super().clean() password = cleaned_data.get("password") password_confirm = cleaned_data.get("password_confirm") if password and password_confirm and password != password_confirm: self.add_error('password_confirm', "Passwords do not match") return cleaned_data def save(self, commit=True): full_name = self.cleaned_data['full_name'] if " " in full_name: first_name, last_name = full_name.split(" ", 1) else: first_name = full_name last_name = "" user = User.objects.create_user( username=self.cleaned_data['username'], email=self.cleaned_data['email'], password=self.cleaned_data['password'], first_name=first_name, last_name=last_name ) student = super().save(commit=False) student.user = user student.classroom = self.cleaned_data['classroom'] if commit: student.save() student.subscribed_subjects.set(self.cleaned_data['subjects']) return student