how to display error message in save method of django - python

I want to display error message in case the instance I am creating is more than the maximum limit I have specified in a certain model. This is a inner condition.
I know that we can hide the + and override the has_add_permission method. This is used for user authentication in my application.
However, I wish to allow the instance to be created for a certain login who is a superuser based on the inner condition.
ValidationError gives me error u' max...' ValidationError at the url...
Can anyone guide?

I don't know what an "inner condition" is.
However, you don't do this in the save method. You do it in a validator. For instance, you could define a clean method on your model to handle this, or use a custom form with the validation in.

Related

What does clean mean in Django?

This is an obvious question for everyone, but I don't understand what the term "clean" means. I can use clean_data, and use form validation on my forms. However, I still don't understand what this means.
In order to use validation, do I always need to use the keyword "clean"?
As stated in documentation
The clean() method on a Field subclass is responsible for running
to_python(), validate(), and run_validators() in the correct order and
propagating their errors. If, at any time, any of the methods raise
ValidationError, the validation stops and that error is raised. This
method returns the clean data, which is then inserted into the
cleaned_data dictionary of the form.
Clean is preventing dirty data in DB
As far as i have understood ..all the implicit validations are performed using clean..
which is performed when we check for the form validity using is_valid:
but we can add our own validations to it by overriding the function clean():
what we have to do is we call the super().clean() such that all the implicit validations are done by the clean() defined by django and then add our own validations to it if necessary...
when you call the super().clean() it returns the dictionary containing the cleaned_data..
you can store it in a variable ...
or else you can access the dictionary using self.cleaned_data

django save(commit=False) versus full_clean

I am working on a django project and creating many model instances from batch upload form. I am creating many unsaved model instances in order to test them for errors as I don't want to enter any instances until the user has submitted a full set of valid records to avoid unintentional duplications within the database. My question is whether there is a good reason to use either save(commit=False) or full_clean on the unsaved model instances. I am currently using full_clean, but not sure what the differences/benefits are of one versus the other.
Calling full_clean() is the correct way to validate a model instance.
from django.core.exceptions import ValidationError
try:
obj.full_clean()
except ValidationError:
# handle invalid object
When dealing with a model form, calling is_valid() will perform the model validation, so you don't have to call full_clean() manually.
Calling save() with commit=False doesn't perform model validation. Instead, it gives you the opportunity to change the object before you save it to the database. A common example is to set the user attribute to the user that is currently logged on.

Newfies-dialer Call Reports module

I have newfies dialer project, i would like to add a new field in Call Reports section.
I have lot of field that are unused in contact model. One of them can be used for this special id for my purpose.
How can i do that? Please help me anyone who familiar with newfies-dialer.
Newfies-Dialer is based on the Django framework, so it's good to know about Django to hack on the project.
You will notice in Newfies-Dialer that there is a template called: dialer_cdr/templates/dialer_cdr/voipcall_report.html
in which we display the data that is passed from the view.
So then in dialer_cdr/views.py, you have a view function which is in charge of rendering template and pass it some data. There, you can either modify voipcall_list object to add extra data to it, like info from the contact model, or pass an other object to data.
Here a link to the function handling this view: https://github.com/Star2Billing/newfies-dialer/blob/v2.12.2/newfies/dialer_cdr/views.py#L169

Django pre_save signal - would an exception fail the transaction?

I want to do some custom actions before a user is created. and I thought of using the pre_save signal for that. And in case one of those action would raise an exception stop the transaction, abort creating the user etc.
Is this the way to go? would it abort the save if something fails in this step (this is the required behavior) I suspect so but couldn't find docs about it.
What is the best practice for getting the future user.id. from my understanding it doesn't exists yet in pre-save but I need it as input for some of the extra custom actions.
Thanks
From the docs:
There's no way to tell what the value of an ID will be before you call
save(), because the value is determined by your database, not by
Django.
So if your pre-save processing requires the user.id, I am afraid this is not possible.
Here is the two part answer:
Yes, raising an exception in the pre_save() signal will abort the call to the save() method. For example, I did this in my pre_save():
if SOME_TEST:
raise exceptions.ParseError(detail="I reject your data. Here is why.")
Note: This was using the DRF exceptions, but I will assume you know how to raise whatever exception you prefer.
You could use the post_save() signal to get the id AFTER the save() method. But if that will not work for you, then below is my original explanation of some tactics to do what you want in the pre_save():
In the pre_save you can access User.objects.all() (if you import the User model, of course). If you are using the standard User model then the User.id value is AUTO INCREMENT. So if you NEED to know what the value WILL be for the new user, just get the highest User.id currently in the database (ie: the id of the last user created). Here is a simple query to do this:
last_user = User.objects.latest('id')
Then of course, last_user.id will give you the value of the id for the last user created and if you add one to that you will have the next user id. Of course, if you have a busy site you may have some problems with simultaneous user creation. The risk is that this value is received by two (or more) User creation attempts and one (or more) of them ends up wrong.
Of course, you can always set another field to be primary_key=True and this will replace the id field on the model. Then you can devise any sort of indexing mechanism that you can dream up! You could use a hash value of a unique characteristic. For example: The User.username has a Unique constraint, you could hash or hex encode that as a numeric ID to pre-determine the User.id. Or you could leave the id field in place and set it manually in the pre_save by assigning a value to obj.id. It could be anything you want. Even a hash value!

Model and Validation Confusion - Looking for advice

I'm somewhat new to Python, Django, and I'd like some advice on how to layout the code I'd like to write.
I have the model written that allows a file to be uploaded. In the models save method I'm checking if the file has a specific extension. If it has an XML extension I'm opening the file and grabbing some information from the file to save in the database. I have this model working. I've tested it in the built-in administration. It works.
Currently when there's an error (it's not an XML file; the file can't be opened; a specific attribute doesn't exist) I'm throwing an custom "Exception" error. What I would like to do is some how pass these "Exception" error messages to the view (whether that's a custom view or the built-in administration view) and have an error message displayed like if the forms library was being used. Is that possible?
I'm starting to think I'm going to have to write the validation checks again using the forms library. If that's the case, is it possible to still use the built-in administration template, but extend the form it uses to add these custom validations?
Anything to help my confusion would be appreciated.
UPDATE:
Here's my model so far, for those who are asking, "nzb" is the XML file field.
http://dpaste.com/hold/6101/
The admin interface will use the Form you associate with your model; your own views can also use the form.
This is exactly what I'd like to do. However, I don't know how to associate my forms with my models. When ever I've created forms in the past they've always acted as their own entity. I could never get the administration views to use them while using the ModelForm class. Can you shead any light on this?
I've read over the link you gave me and it seams to be what I've done in the past, with no luck.
Getting attributes from the file, should probably be a method.
Sorry, could you please elaborate on this? A method where?
UPDATE:
It seams I've been compleatly missing this step to link a form to the administration view.
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin
This should now allow me to do the validation in a Form. However, I'm still confused about how to actually handle the validation. S.Lott says it should be a method?
The Form errors are automatically part of the administrative view.
See http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation
You're happiest if you validate in a Form -- that's what Forms are for. The admin interface will use the Form you associate with your model; your own views can also use the form.
Getting attributes from the file, should probably be a separate method of the model class. The separate method of the model class can be used by the save() method of the model class or invoked at other times by view functions.
"I could never get the administration views to use them while using the ModelForm class."
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin
"I'm still confused about how to actually handle the validation. S.Lott says it should be a method?"
Validation in a form is done with a clean() method or a clean_somefield() method.
The "Adding custom validation to the admin" link (above) shows how to add the clean_name method to the "MyArticleAdminForm" form.
If you're still confused, trying actually typing the code from the Django web page and see what it does.
I guess the best way would be to implement a special field class that extends FileField with custom validation of the uploaded file.
The validation is implemented in the field's clean method. It should check the XML file and raise ValidationErrors if it encounters errors. The admin system should then treat your custom errors like any other field errors.
The ImageField class is a good example of special validation like this — I recommend just reading through the source.
You can provide a form that will be used by the admin site. You can then perform validations in the form code that will be displayed in the admin area.
See the docs on the admin site, and in particular the form attribute of ModelAdmin.
"I'm throwing an custom "Exception" error " - Where exactly are you throwing the exception ? In your model or in your view ?
I am confused with your question, so I am assuming that you should be asking 'Where should I catch input errors if any ? ' to yourself.
The Model and View as I see are like pieces in a small assembly line.
View/ Form validation is the first action which should be performed. If there is any issue with the input data through the forms. It should be prevented at the form level using form.is_valid() etc.
The models functionality should be to provide meta information about the entity itself apart from performing CRUD. Ideally it should not be bothered about the data it is getting for the CRUD operations.

Categories

Resources