Model and Validation Confusion - Looking for advice - python

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.

Related

How can I submit a Django formset within python code?

Background. We want our users to check if the metadata we read out of several images is correct.
Therefore, we show the retreived data in a formset to let the user check everything.
In case the metadata has errors (that happens) we would like to display them as form errors here.
Problem. To obtain the error messages we need bound forms. Feeding our various data into a bound ModelFormSet and taking care of the ManagementForm is ... not so simple. With the unbound version everything works fine.
Idea. If we could produce an unbound form and submit it within the python code, that would be a simple way to get the POST data we need to create the bound form.

What's wrong with putting all your custom validation in your model?

Django's ModelForms are cool, but I'm having trouble wrapping my head around why you'd ever want to put data integrity rules in your forms, when they could just be in the models themselves, per https://stackoverflow.com/a/18876223/1207253, who goes on to write "This isn't done by default, as explained here, because it interferes with certain features..."
I've read through the cited links and https://github.com/danielgatis/django-smart-save and still don't understand why this isn't the recommended approach. What are the features this approach interferes with? Excluded fields works. Default values works. What am I missing?
Only downside I can think of is that full_clean or clean (whichever you call in save) will be called twice if saving models through admin. There shouldn't be any side effects as such.
Form validation puts restriction on how the user enters data, Model validation specifies how that data must be processed / validated further before storing it in the db. So, unless your forms are very complicated, validating in the model works just fine.
Use whichever you are most comfortable with and adhere to it throughout the project as there is no strong convention here.

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

Design of CBVs in Django

I'm currently trying to get into "Class Based Views" with Django 1.5.
From the design perspective i wonder where to put the logic to process data comming from a form in a simple FormView.
I know that all form validation code comes into the method form_valid(). But where to put things which processes data of the form. I read that its somehow inappropriate to put too much logic into the form_valid() method.
There are the get(), post(), get_context_data(), head(), etc. methods... which should I use in which case?
Form validation, data cleaning, etc goes with the form class in the clean methods
Processing of a valid form should go in an overridden form_valid method
That's it! If your use-case is more complicated you can call out to other methods of your creation from form_valid...
Any answer to this question is open for discussion. That said, views are just Python classes, so you could overwrite any method to customize things accordingly.
It is also perfectly legit to create an extra method on your class to handle data processing.

Django ModelForm, having a foreign key as a hidden field

I'm basically building a very trivial form. Let's stick to the books/publisher examples given in the django tutorials and build upon that.
I have a user login to the web app, at which point the first thing they can do is click on a publisher. This publisher then gets saved for their session. Upon that I take them to a create book form. In there I embed the the publisher's id from the database into a hidden field.
Upon the user submitting an HTTP POST, I do something like:
mybookform = BookForm(request.POST)
if mybookform.is_valid():
abook = mybookform.save(commit=False)
abook.publisher_id = request.POST['publisher_id']
mybookform.save()
Yes there's a few naive things done here, such as blindly grabbing the publisher_id and verifying if it's indeed a real publisher id, amongst other security issues. Let's just not pay attention to that for the moment.
My question is, is there a better way of handling this? Although hypothetically this example doesn't make logistical sense, in my particular app the example actually makes sense. The problem is I get a ValueError exception saying publisher_id needs to be a Publisher instance.
Now I can easily retrieve a publisher instance with Publisher.objects.filter(id=..) and use that instead. The question is, is it really necessary? Can I avoid the additional query to the database and somehow update this form instance in a more 'elegant' fashion?
Also, is it possible to somehow embed the publisher in a hidden field so that I do not need to do mybookform.save(commit=False) and just do mybookform = BookForm(request.POST) followed by mybookform.save() immediately?
Retrieving the instance of the publisher does protect against client-side changes that might reference a completely invalid publisher.
To your second question, yes you can include that field as a hidden field by overriding the field in the ModelForm with the approriate form field setting the widget to HiddenInput.
There is no better way to do this.
I would use the get_object_or_404 function for this.
And yes, you can prevent this to be modified by the user by setting the model field to editable=False,

Categories

Resources