Custom validation is not working inside forms.py - django

I want to validate my email field like: if email contains [gmail.com,outlook.com,yahoo.com] then I want to raise validation Error. But it's not working, I don't know what i am doing wrong. plz help me
views.py
from django.shortcuts import render
from django.views.generic import View
from access.utils import is_valid
from access.mixin import HttpResponseMixin
import json
from access.forms import Employer_Form
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
#method_decorator(csrf_exempt,name = 'dispatch')
class Emp_Registration_view(View,HttpResponseMixin):
def post (self,request,*args,**kwargs):
data = request.body
json_data = is_valid(data)
if not json_data:
return self.render_http_response(json.dumps({'msg':'Please send valid json only'}),status=400)
emp_data = json.loads(data)
form= Employer_Form(emp_data)
if form.is_valid():
form.save(commit=True)
return self.render_http_response(json.dumps({'msg':'Registered Successfully'}))
if form.errors:
return self.render_http_response(json.dumps(form.errors),status=400)
forms.py
from access.models import Employer_Registration
from django import forms
class Employer_Form(forms.ModelForm):
def clean_email(self):
email = self.cleaned_data['emp_email']
email_lists = ['gmail.com','yahoo.com','outlook.com','hotmail.com']
data = emp_email.split('#')
if data in email_lists:
raise forms.ValidationError("email is not valid")
return email
class Meta:
model = Employer_Registration
fields = '__all__'

Your method should be named clean_emp_email, because the field is named emp_email. Otherwise it won't be called.

Seems like you are splitting on # so if you split example#gmail.com it will be [example , gmail.com] and that you are comparing in this line exactly
if [example , gmail.com] in email_lists
so it is not found I suggest you to do you can omit splitting and find in substring as
for i in email_lists:
if i in self.cleaned_data['emp_email']:
raise forms.ValidationError("email is not valid")
After #Alexandr Tatarinov answer you should also call the clean_field_name or simply clean

Related

Contact() got an unexpected keyword argument 'listing'

`from django.shortcuts import render, redirect
from .models import Contact
from django.contrib import messages
Create your views here.
def Contact(request):
if request.method == 'POST':
listing_id = request.POST['listing_id']
listing = request.POST['listing']
name = request.POST['name']
email = request.POST['email']
phone = request.POST['phone']
message = request.POST['message']
user_id = request.POST['user_id']
realtor_email = request.POST['realtor_email']
contact.save()
messages.success(
request, 'Your request has been submitted, a realtor will get back to you soon')
rn redirect('listings'+listing_id)
`
i'm trying to save the data from database. but give the error TypeError.
This statement
from .models import Contact
You have defined a method with the name Contact and you are trying to import a module from the .models and also it's name is Contact
So to fix the issue.
You need to change the Method name or import the module with any alias name.
for Eg:
from .model import Contact as contact_module
or change the method name to any like..
def contact_method(request):
#.....

How to OR Django model field validators?

Does anyone know how to OR together Django model field validators?
Something like this:
example_field = models.CharField(max_length=255, validators=[validator1|validator2])
I am guessing that there is a way and it involves the Q operator, but I can't find what it is exactly.
You can do the validation in a function itself:
from django.core.exceptions import ValidationError
from django.db import models
def combined_validator(value):
try:
return validator1(value)
except ValidationError:
return validator2(value)
class MyModel(models.Model):
example_field = models.CharField(
max_length=255,
validators=[combined_validator]
)
If validator1 does not detect any trouble, then the control flow is returned, and thus we are safe. If it raises a ValidationError, then we fallback on validator2. If that does not raises an error, then we are again safe. Otherwise, the error will raise out of combined_validator.
I needed an OR-validator as well, so I made a little reusable validator that
can accept any number of sub-validators that are OR-ed together.
Inspired by Django's own validators, so should work everywhere (only tested in Django Rest Framework serializer)
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator, RegexValidator
from django.utils.deconstruct import deconstructible
from rest_framework import serializers
#deconstructible # allows usage in migrations
class OrValidator:
message = 'Enter a valid value.' # customize this based on the sub-validators
code = 'invalid'
def __init__(self, validators, message=None, code=None):
self.validators = validators
self._errors = []
if code is not None:
self.code = code
if message is not None:
self.message = message
def __call__(self, value):
for validator in self.validators:
try:
return validator(value)
except ValidationError as e:
# save error for debugging
self._errors.append(e)
# non matched, raise error
raise ValidationError(self.message, code=self.code)
def __eq__(self, other):
return (
self.validators == other.validators and
isinstance(other, self.__class__) and
self.message == other.message and
self.code == other.code
)
class UsernameValidator(RegexValidator):
regex = re.compile(r'^[-\w]+\Z', re.UNICODE)
# example usage in Django Rest Framework (should work in forms and models as well)
class ResetPasswordSerializer(serializers.Serializer):
email_or_username = serializers.CharField(
required=True,
validators=[
OrValidator(
[EmailValidator(), UsernameValidator()],
message='Enter a valid email or username',
),
],
)

AttributeError at has no attribute 'objects'

AttributeError type object 'Data_Point ' has no attribute 'objects'plz check and correct me
AttributeError at /
type object 'myProduction' has no attribute 'objects'
model":
from django.db import models
from django.contrib.auth.models import User
class Production(models.Model):
title=models.CharField(max_length=120)
def __str__(self):
return self.title
My Form
from django import forms
from.models import Production
class myProduction(forms.ModelForm):
class Meta:
model=Production
fields =['title']
class Raw_Pro(forms.Form):
title = forms.CharField()
My View
from django.shortcuts import render
from .form import myProduction,Raw_Pro
def my_index(request):
my_form=Raw_Pro()
if request.method=='POST':
my_form=Raw_Pro(request.POST)
if my_form.is_valid():
myProduction.objects.create(my_form.cleaned_data)
else:
print(my_form.errors)
context={"form":my_form}
return render(request, "index.html",context)
You make some mistakes here:
myProduction here is your ModelForm (defined in forms.py), not your model (this is Production, defined in `models.py);
you here use Raw_Pro as form, which is not a ModelForm, which is likely not what you want to use;
in case of a successful form, you can use mymodelform.save() to create/edit the object; and
if the creation is successful, you should redirect to a page, for example the same page. By not doing so, a refresh of the user, would trigger a POST with the same parameters.
from django.shortcuts import render
from .form import myProduction
def my_index(request):
if request.method == 'POST':
my_form = myProduction(request.POST)
if my_form.is_valid():
my_form.save()
return redirect(my_index) # or somewhere else
else:
my_form = myProduction()
context = {"form":my_form}
return render(request, "index.html",context)
Note: as specified by PEP-8 [Python-doc], you should use camelcase starting with an Uppercase for class names. So you better rename your myProduction class to MyProduction, or much better ProductionForm, since then it is clear what that class is doing.

User matching query does not exist - django

I have a page which shows the user and their about. And in that, there's a link to update their about. But when I open that link it shows me with this error:
DoesNotExist at /profile/user/update_about/
User matching query does not exist.
And the traceback hightlights this line, which from the profile method in the views:
13. user = User.objects.get(username=unquote(user_name))
However this error does not occur when I load the profile method. It occurs only on the update_profile method in the views.
views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from urllib import unquote
from django.contrib.auth.models import User
from models import About
from forms import AboutForm
# Create your views here.
def profile(request, user_name):
user = User.objects.get(username=unquote(user_name))
about = About.objects.get_or_create(user=user)
about = about[0]
return render(request, 'user_profile.html', {
'user':user,
'about_user':about
})
def update_about(request, user_name):
user = User.objects.get(username=unquote(user_name))
if request.method == 'POST':
form = AboutForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
about = About.objects.get(user=user)
form = AboutForm(initial={'dob':about.dob})
return render(request, 'update_about.html',{
'form':form
})
urls.py
urlpatterns = patterns('',
# Examples:
url(r'(?P<user_name>[\w#%.]+)/$', 'user_related.views.profile', name='profile'),
url(r'(?P<user_name>[\w#%.]+)/update_about/$', 'user_related.views.update_about', name='update_about'),
What is causing this? Your help will be very much appreciated. Thank you.
You forgot to add the caret sign (^) at the first position of regex. So the first regex matched "update_about/" part of the url.
Fixed code:
url(r'^(?P<user_name>[\w#%.]+)/$', 'user_related.views.profile', name='profile'),
url(r'^(?P<user_name>[\w#%.]+)/update_about/$', 'user_related.views.update_about', name='update_about'),

How to write Django ApiView that returns a Boolean based on presence of model?

I am using Django's native Authorization/Authentication model to manage logins for my WebApp. This creates instances of the User model.
I would like to write a simple class-based-APIView that can tell me if a specific email is already used (IE: Is there already a user with the given email in my database?). Which generic view should I inherit from and what would the view look like?
Thanks
I would like to write a simple class-based-APIView that can tell me if
a specific email is already used (IE: Is there already a user with the
given email in my database?). Which generic view should I inherit from
and what would the view look like?
Sometimes, simple is best:
import json
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.http import require_http_methods
from django.contrib.auth import get_user_model()
#require_http_methods(['GET'])
def check_email(request, email=None):
e = get_object_or_404(get_user_model(), email=email)
return HttpResponse(json.dumps({'result': 'Found'}),
content_type="application/json")
Well you can try something like:
view
class MyView(View):
...
def post(self, request, email_address, *args, **kwargs):
response_data = {}
if User.objects.filter(email=email_address).exists():
response_data['result'] = 'success'
response_data['message'] = 'email exists'
else:
response_data['result'] = 'failed'
response_data['message'] = 'Email does not exist'
return HttpResponse(json.dumps(response_data), content_type="application/json")
url:
url(r'^something/(?P<email_address>[\w.%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$',MyView.as_view()),)