0

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')
6
  • Have a look at stackoverflow.com/questions/18803112/… Commented Oct 28, 2019 at 6:43
  • @WiRai please check I have updated the question can you tell me why its working for my other model Works_in Commented Oct 28, 2019 at 6:50
  • 1
    Perhaps you save instances from a model form which results in a call to models full_clean which calls clean? open a django shell and create an object without a form, clean should imho not run. Commented Oct 28, 2019 at 6:58
  • Possible duplicate of Django doesn't call model clean method Commented Oct 28, 2019 at 7:00
  • 2
    Himanshu, it's explicit in the docs that clean won't be called automatically. docs.djangoproject.com/en/2.2/ref/models/instances/… Commented Oct 28, 2019 at 7:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.