So I having this model where I am storing the information that my entity is sending .
class NewProvisionalEmployeeMail(models.Model):
offer_id = models.AutoField(primary_key=True)
email = models.EmailField(max_length=70, null=False, blank=False, unique=False)
token = models.TextField(blank=False, null=False)
offer_sent_by = models.CharField(max_length=50)
position_assigned = models.CharField(max_length=50, null=False, blank=False, default="Developer")
def __str__(self):
return str(self.offer_sent_by) +" to " + str(self.email)
def clean(self):
if(NewProvisionalEmployeeMail.objects.filter(email=str(self.email)).exists()):
NewProvisionalEmployeeMail.objects.filter(email=str(self.email)).delete()
What was expected : Before saving data to this model, I expect the clean method to be called automatically. I have tried this with my other models over there it was working but its not working over here. This is the part where I am saving the data.
def sendoffer(request):
context = {}
hostname = request.get_host() + "/dummyoffer"
if request.method=='POST':
email = request.POST.get('email')
position = request.POST.get('opt')
context['success_message'] = "Mail has been sent!!!"
token = get_secret_key(email)
msg=EmailMultiAlternatives('ATG',"Hello\n we are from atg.dev.party\n Click on this link to get offer","[email protected]",[email])
message = "http://" + hostname + "/" + token
msg.attach_alternative(message,"text/html")
msg.send()
newusermail = NewProvisionalEmployeeMail(email=email, token=token, offer_sent_by=request.user.username, position_assigned=position)
newusermail.save()
return render(request, 'mainapp/offer.html',context)
newusermail.save() is the part where the data is going to be saved and before that I expect clean method to be called which checks for email if it already exists in our database and if it does we delete it.
I know there are several ways to achieve this but my question if why the clean method is not getting called?
EDIT : When I am overriding the save method and explicitly calling the clean method its working. Isn't the clean method gets automatically called. Why do I need to call it explicitly.
def save(self, **kwargs):
self.clean()
return super(NewProvisionalEmployeeMail, self).save(**kwargs)
It was however working fine for my other models.
EDIT 2 :
I know we can do it using the save method but my question is why is it then working for my other models. For example in one of my model Works_in its working totally fine.
class Works_in(models.Model):
emp_name = models.ForeignKey(User, related_name='works_emp_name', to_field='username', on_delete=models.CASCADE)
dept_name = models.ForeignKey(Department, blank=False, null=False, to_field='name',related_name='works_on_dept', on_delete=models.CASCADE)
class Meta:
unique_together = ["emp_name", "dept_name"]
def __str__(self):
return str(self.emp_name) + " " + str(self.dept_name)
def clean(self):
emp_list = list(Works_in.objects.filter(dept_name=str(self.dept_name)).values_list('emp_name'))
count = Emp_position.objects.filter(emp_uname__in=emp_list, position_name="Manager")
is_manager = Emp_position.objects.filter(emp_uname = self.emp_name, position_name='Manager')
# first the employee position should be added and then only department
if(len(Emp_position.objects.filter(emp_uname = self.emp_name)) == 0):
raise ValidationError(f"{self.emp_name}'s Position hasn't been added yet")
if len(count)>=1 and len(is_manager)>=1:
raise ValidationError('Manager already assigned to this department')
Works_incleanwon't be called automatically. docs.djangoproject.com/en/2.2/ref/models/instances/…