i am trying to validate unique user name in the registration form. while i click the submit button after entering the details in the register form, instead of raising a validation error with the given message, it fails and errors out Validationerror at /register/. i am also trying to print the string inside the function. but it doesnt print that too. is it actually calling the clean function. i am using self to achieve this. it should be called !. am i misiing something?
class Register_Form(forms.Form):
user_id = forms.CharField(label="User Name",widget = forms.TextInput(
attrs = {"class":"form-control"}
))
email_id = forms.CharField(label = "Email",widget = forms.EmailInput(
attrs = {"class":"form-control"}
))
password = forms.CharField(label = "Password",widget = forms.PasswordInput(
attrs = {"class":"form-control"}
))
confirm_pass = forms.CharField(label = "Confirm Password",widget = forms.PasswordInput(
attrs = {"class":"form-control"}
))
def clean_username(self):
user_id = self.cleaned_data["user_id"]
print("Entered")
ue = User.objects.filter(username=user_id)
if ue.exists():
raise forms.ValidationError("User name not available")
return user_id
It's not being called, the fact you pass self doesn't mean it'll automatically run, you are just extending your function with self so that it can inherit it's attributes.
Somewhere inside your class you'll have to run self.clean_username(), alternatively if you construct the class, e.g. RF = Register_Form() you'll have to call RF.clean_username()
Related
I create a Django form to create a template (that is an object) with some attributes. The user that want to create this template, obviously, should give a name to template.
I write clean name() method that checks if a template with that name already exists but now I want to create a method that shows an error message if the user does not provide a name for the template that he's creating. How can I do?
This is the django model for the templateForm with his fields:
class TemplateForm(BaseForm):
enabled_parameters = forms.CharField(widget=forms.HiddenInput())
name = forms.CharField(label=_("name *"))
sport = forms.CharField(label=_("sport"), widget=forms.TextInput(attrs={"readonly": "readonly"}))
owner = forms.CharField(label=_("owner"), widget=forms.TextInput(attrs={"readonly": "readonly"}))
visibility = forms.ChoiceField(label=_("visibility"), choices=Template.VISIBILITIES, widget=forms.RadioSelect())
last_update = forms.CharField(label=_("last update"), widget=forms.TextInput(attrs={"readonly": "readonly"}))
def clean_name(self):
"""check if template's name is unique"""
name = self.cleaned_data.get("name")
template_num = 0
if self.template.pk and name == self.template.name:
template_num = 1
if Template.objects.filter(name=name, team=self.template.team).count() != template_num:
raise ValidationError(_("A Template named {} already exists.".format(name)))
return name
It's always get None in clean() or clean_field(), but it's in self.data.
django 2.x
The fields declaration is:
phone = forms.CharField(
label='',
min_length=phone_number_min,
max_length=phone_number_max,
)
code_length = settings.SMS_CODE_LENGTH
code = forms.CharField(
label='',
min_length=code_length,
max_length=code_length,
)
def clean_code(self):
code = self.cleaned_data.get('code')
phone = self.cleaned_data.get('phone')
result, message = sms_validator.validate(phone, code)
def clean(self):
code = self.cleaned_data.get('code')
phone = self.cleaned_data.get('phone')
result, message = sms_validator.validate(phone, code)
Both of above all run in error:
phone = None
But if
phone = self.data.get('phone')
It's can get the value.
I want to get the phone value in clean_data
Firstly, you must always return the cleaned value from a field clean method. Secondly, it is not safe to access other field values in a field clean method; that is what the overall clean() method is for.
I have this error, how can I fix this?
get() returned more than one Event -- it returned 2!
Can you guys help me understand what that means and maybe tell me in advance how to avoid this error in future?
MODEL
class Event (models.Model):
name = models.CharField(max_length=100)
date = models.DateField(default='')
dicript = models.CharField(max_length=50, default='Описание отсутствует')
category = models.ForeignKey(Category,on_delete=models.CASCADE)
adress = models.TextField(max_length=300)
user = models.ForeignKey(User,related_name="creator",null=True)
subs = models.ManyToManyField(User, related_name='subs',blank=True)
#classmethod
def make_sub(cls, this_user, sub_event):
event, created = cls.objects.get_or_create(
user=this_user
)
sub_event.subs.add(this_user)
VIEWS
def cards_detail (request,pk=None):
# if pk:
event_detail = Event.objects.get(pk=pk)
subs = event_detail.subs.count()
# else:
# return CardsView()
args = {'event_detail':event_detail,'subs':subs}
return render(request,'events/cards_detail.html',args)
class CardsView (TemplateView):`
template_name = 'events/cards.html'
def get (self,request):
events = Event.objects.all()
return render(request,self.template_name,{'events':events })
def subs_to_event (request,pk=None):
event = Event.objects.filter(pk=pk)
Event.make_sub(request.user,event)
return redirect('events:cards')
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
try:
instance = Instance.objects.get(name=name)
except (ObjectDoesNotExist, MultipleObjectsReturned):
pass
get() raises MultipleObjectsReturned if more than one object was found,more info here.
the error is cause by event_detail = Event.objects.get(pk=pk), check your event pk is unique.
Basically, the cls object is getting more than one value on the get part of the 'get_or_create()'. get() returns only a single object whereas filter returns a dict(ish).
Put it in a try/except instead. So you'll have:
try:
event, created = cls.objects.get_or_create(
user=this_user
)
except cls.MultipleObjectsReturned:
event = cls.objects.filter(user=this_user).order_by('id').first()
This way if multiple objects are found, it handles the exception and changes the query to a filter to receive the multiple object queryset. No need to catch the Object.DoesNotExist as the create part creates a new object if no record is found.
I also face the same error:
get() returned more than one -- it returned 4!
The error was that I forgot to make a migration for the newly added fields in the model.
I'm testing a form that I wrote up earlier. For some reason, the test won't pass. It's like the form is ignoring the data I pass it, and I don't see why. The traceback tells me that the user variable in the clean method of the form is None, though a User is definitely passed into the form. The traceback:
... in clean
if user.pk is not userwebsite.user.pk: AttributeError: 'NoneType' object has no attribute 'pk'
The Form:
class CreateAuditForm(forms.Form):
user = forms.ModelChoiceField(queryset=User.objects.all(), widget=HiddenInput)
website = forms.ModelChoiceField(queryset=UserWebsite.objects.all(), widget=HiddenInput)
emails = forms.CharField(
max_length=250,
required=False
)
def clean_user(self):
user = self.cleaned_data.get('user', None)
if not user.groups.filter(name__iexact='subscribed').exists() and not user.groups.filter(name__iexact='addon').exists():
raise forms.ValidationError(_("You must have an active subscription to request \
website audits. Please try again after subscribing to us."))
return user
def clean(self):
data = self.cleaned_data
user = data.get('user')
userwebsite = data.get('website', None)
if userwebsite.user:
if user.pk is not userwebsite.user.pk:
raise forms.ValidationError(_("Sorry, try again."))
elif userwebsite.addon:
if user.pk is not userwebsite.addon.pk:
raise forms.ValidationError(_("Sorry, try again."))
return self.cleaned_data
def save(self):
# Action
The Test:
class CreateAuditFormTestCase(TestCase):
def setUp(self):
super(CreateAuditFormTestCase, self).setUp()
self.form = CreateAuditForm
...
self.website = Website.objects.create(
title="permanence",
url="https://www.badabuyhere.com",
display="www.bababuyhere.com")
self.unsubscriber = User.objects.create(
username="adiagojesse",
first_name="adiago",
last_name="jesse",
email="bannerfare#coldmount.com",
password="tigermountainvalley"
)
self.unsubscriberwebsite = UserWebsite.objects.create(
user=self.unsubscriber,
website=self.website,
is_competitor=False
)
...
def test_user_validation(self):
data = {
"user":self.unsubscriber.pk,
"website":self.unsubscriberwebsite.pk,
"emails":"john#gmail.com, jeff#gmail.com"
}
self.assertTrue(self.unsubscriber)
self.assertTrue(self.unsubscriberwebsite)
audit = self.form(data)
self.assertEqual(audit.is_valid(), False)
This is probably a simple issue that I can't pick up on, which is what's frustrating me, lol. Help would be appreciated.
My guess is that in CreateAuditForm.clean, useris None because clean_user raised a ValidationError. The ValidationError comes from the fact that the user does not have the groups he needs.
Another issue I see is that to test equality between model instances in Django, you should not use primary keys but test using the instances directly, using == and not is. (See https://stackoverflow.com/a/13650309/1644198 for more information on is and ==)
Example:
if user != userwebsite.user:
# etc...
I'm trying to keep track of the answers from users who sends a "password" into the Twilio app so they can answer a series of questions. First, it'll probably be best to check that "from_number" exists in the database, then create a new Caller if it isn't.
In models.py:
class Callers(models.Model):
body = models.CharField()
from_number = models.CharField()
last_question = models.CharField(max_length=1, default="0")
In views.py:
def HelloThere(request):
body = request.REQUEST.get('Body', None)
from_number = request.REQUEST.get("From",None)
if Caller.objects.filter(from_number == from_number):
if last_question == "0":
caller = Caller(message = "first question". last_question = "1")
caller.save()
return HttpResponse(str(resp))
if last_question == '1':
# so on and so forth
else:
caller = Caller(body=body, from_number=from_number, last_question='0')
caller.save()
message = "What is the password?"
I don't think I can use request.user.is_authenticated().
/Is it a bad idea to have so many of the same field names? "body=body=Body?
First about the model:
class Callers(models.Model):
body = models.CharField()
from_number = models.CharField()
last_question = models.IntegerField(default=0) # if you have more than 10 question then I guess using IntegerField is better here
Then the view:
def hello_there(request): # this is a function, so use lower case with underscore for name
body = request.REQUEST.get('Body', None)
from_number = request.REQUEST.get("From",None)
try:
caller = Caller.objects.get(from_number=from_number) # using get() is better than filter here since I guess you want unique caller field in DB, right?
except Caller.DoesNotExist:
caller = None
if caller:
if caller.last_question == 0:
# update the caller ?
caller.last_question = 1
caller.body = 'Something'
caller.save()
# ... your code ...
return HttpResponse(str(resp))
if last_question == 1:
# so on and so forth
# if you have repeated process here, make a function to update caller to be DRY
else:
new_caller = Caller(body=body, from_number=from_number, last_question=0)
new_caller.save()
message = "What is the password?"
request.user.is_authenticated() is only for User model so you can't use it. And it's okay to use same name for different things, for example body in your view can be variable or argument. If it isn't clear for you then you can pick different name then.
Hope it helps!