Django ModelForm as a layer of data validation
Question:
I have an authorization form, and I get an error – "already have a user with this email". I want to use the forms as a layer of validating the data.
I now, that i can pass instance of CustomUser in my form, but i can`t do it. Need other solution.
@require_http_methods(["POST"])
@not_logged_in_user_only()
def auth(request: WSGIRequest):
form = UserAARForm(data=request.POST)
if not form.is_valid():
return JsonResponse({'status': 'error', 'message': f'{form.errors.as_json()}'})
else:
service = AuthenticateAndAuthOrRegistrUser()
service.execute(req=request, data=form.clean())
if service.errors:
return HttpResponseServerError()
return redirect("profile_page")
class SoundHomeUsers(models.Model):
email = models.EmailField(
max_length=254,
unique=True,
validators=[UserEmailValidator().is_valid])
password = models.CharField(
max_length=254,
validators=[UserPasswordValidator().is_valid])
class UserAARForm(ModelForm):
class Meta:
model = SoundHomeUsers
fields = ['email', 'password']
Answers:
Make the form a new
and edit
form, that way you won’t get that error!
General format:
# Grab existing object by email and edit, or grab None and create new
def auth_0(request: WSGIRequest):
user_instance = None
if request.POST.get('email'):
# will return `None` if it doesn't find a User
user_instance = SoundHomeUsers.objects.filter(email=request.POST.get('email')).first()
form = UserAARForm(data=request.POST, instance=user_instance)
# do the things
# Grab existing object by pk or None
# Generally I always do it by PK and just post using hidden fields
# Usually it's loaded into a `user's profile` or something
def auth_1(request: WSGIRequest):
user_instance = None
if request.POST.get('pk'):
# will return `None` if it doesn't find a User
user_instance = SoundHomeUsers.objects.filter(pk=request.POST.get('pk')).first()
form = UserAARForm(data=request.POST, instance=user_instance)
# do the things
I solve the problem, by extending ModelView
and overriding method validate_unique
. This allow me to use default ModelView validation queue, as just fields validation.
class BaseLayerValidationForm(ModelForm):
def validate_unique(self):
pass
class UserAARForm(BaseLayerValidationForm):
class Meta:
model = SoundHomeUsers
fields = ['email', 'password']
I have an authorization form, and I get an error – "already have a user with this email". I want to use the forms as a layer of validating the data.
I now, that i can pass instance of CustomUser in my form, but i can`t do it. Need other solution.
@require_http_methods(["POST"])
@not_logged_in_user_only()
def auth(request: WSGIRequest):
form = UserAARForm(data=request.POST)
if not form.is_valid():
return JsonResponse({'status': 'error', 'message': f'{form.errors.as_json()}'})
else:
service = AuthenticateAndAuthOrRegistrUser()
service.execute(req=request, data=form.clean())
if service.errors:
return HttpResponseServerError()
return redirect("profile_page")
class SoundHomeUsers(models.Model):
email = models.EmailField(
max_length=254,
unique=True,
validators=[UserEmailValidator().is_valid])
password = models.CharField(
max_length=254,
validators=[UserPasswordValidator().is_valid])
class UserAARForm(ModelForm):
class Meta:
model = SoundHomeUsers
fields = ['email', 'password']
Make the form a new
and edit
form, that way you won’t get that error!
General format:
# Grab existing object by email and edit, or grab None and create new
def auth_0(request: WSGIRequest):
user_instance = None
if request.POST.get('email'):
# will return `None` if it doesn't find a User
user_instance = SoundHomeUsers.objects.filter(email=request.POST.get('email')).first()
form = UserAARForm(data=request.POST, instance=user_instance)
# do the things
# Grab existing object by pk or None
# Generally I always do it by PK and just post using hidden fields
# Usually it's loaded into a `user's profile` or something
def auth_1(request: WSGIRequest):
user_instance = None
if request.POST.get('pk'):
# will return `None` if it doesn't find a User
user_instance = SoundHomeUsers.objects.filter(pk=request.POST.get('pk')).first()
form = UserAARForm(data=request.POST, instance=user_instance)
# do the things
I solve the problem, by extending ModelView
and overriding method validate_unique
. This allow me to use default ModelView validation queue, as just fields validation.
class BaseLayerValidationForm(ModelForm):
def validate_unique(self):
pass
class UserAARForm(BaseLayerValidationForm):
class Meta:
model = SoundHomeUsers
fields = ['email', 'password']