On 4/05/2018 7:02 AM, jt.oldn...@gmail.com wrote:
Thanks for the response Mike.

I generally don't like it when a design has to change to fit a framework,

I agree. My design is almost entirely in the models. I want an API to be able to work without Django forms.

however, in this case I decided to try your solution. I ran into a couple of problems though :-(  1) The fields that I'm looking up were required fields. Validation failed and error messages were displayed until I changed my model to not require those fields (which creates other problems I'd need to fix). Is there a way to hook in before validation?

Maybe but not in the model. I think you should be able to intercept form validation. But see below.

I over-road the model save function. Would the pre-save signal method fix this problem?
No
Or maybe ModelAdmin.save_model?
Don't know. Possibly.

Django forms automatically do all the python-wise cleaning of data prior to the model's save() being called by the form If you are putting data independently from the form into fields inside the save() method (or via a pre_save hook) you have to be certain it is valid data.

I might be wrong but I don't think there is any effective difference between pre and post save signals and my approach. Maybe transaction management. Maybe not. This is my exact substance.save() method ...

    def save(self, *args, **kwargs):
        links = self._pre_save()
        super(Substance, self).save(*args, **kwargs)
        self._post_save(links)
        self._post_post_save()

Stuff which occurs in _pre_save() happens before the record is saved to the database. For example, the record may not yet have a primary key because it is new and hasn't ever been saved to the database. Stuff in _post_save() and _post_post_save() happens afterwards. I use those to create related records if required because by then (under normal circs) I can guarantee self.id is no longer null.

The last thing which happens prior to save() is the model's clean() method (if it exists) is called by the form. I put checks in there to be certain data in whatever fields I care deeply about is valid and raise a ValidationError if not. If that happens, the save() is aborted and the user has to fix the problem before trying again. Here is an example ...

    def clean(self):
        if self.physical_state is None:
            raise ValidationError('Physical form is required')

If you are getting external data you have no choice but to be certain it is good data. You need to validate it Python-wise en route to the destination model fields, perhaps in _pre_save() and business-rule-wise in Employee.clean()

The actual validation checks can be factored out and called from clean() or anywhere else such as save().

The actual sequence of events (form calls model.clean() before model.save()) indicates to me that Employee.clean() ought to be able to insert (clean) data into Employee fields before running its own business rule validation. However, whenever I have tried this I haven't been successful. Therefore I'm missing something. Maybe transaction management. Maybe someone can enlighten me?

A side note is that if you are not using a form, clean() does not get called. This matters for unit testing where there is no form. You have to deliberately call clean() to get the benefit of any checks.

 2) The desired result of the lookup would be to display the change form so that the information could be verified.

Sorry but that implies javascript and an API to fetch the data for verification if you want to do it all at once.

OTOH maybe you could save the Employee model without the external data and use a separate 1:1 model to carry it. That could be fetched separately after the Emplyee.save() has run. In my scenario it would be fetched in the _post_save() method and verified python-wise in there before adding the 1:1 model if it didn't already exist. The Employee would need to be saved again so the 1:1 model gets saved. The 1:1 model could check the business rule logic in its clean() method. Maybe the advantage here would be splitting the activity into separate atomic transactions and a 1:1 model validation error wouldn't interrupt the preceding Employee.save()

In other words, if doing the lookup, 'SAVE' (and 'Save and add another') should behave as if 'Save and continue editing' had been selected.

There is no save/clean difference between any of those. Just what happens next in the Admin.



--
You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com <mailto:django-users+unsubscr...@googlegroups.com>. To post to this group, send email to django-users@googlegroups.com <mailto:django-users@googlegroups.com>.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/26f88b4c-b2dd-4bce-aea7-d885295aa609%40googlegroups.com <https://groups.google.com/d/msgid/django-users/26f88b4c-b2dd-4bce-aea7-d885295aa609%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/e3b0a30d-f32b-4c22-5380-e6343cfc5ad5%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

Reply via email to