Django form error handling architecture - python

In the clean method of my form class I am working with many different inputs from the billing, contact, and account sections of the form. As such there are many self.add_error statements and many fields that depend on other fields in order to validate.
I have noticed that after adding an error for a field I am unable to access that field any more. This is strange as you can add more than one error to a field, but that is not the issue.
I am seeing this method grow more complicated and unreadable, is there a good way to do this so the person that comes after me will understand it? I don't feel that the code ordering to prevent access after error is appropriate. My only thought is to set error variables in clean and call a different method at the end to add the errors to the fields.
Thanks
Edit: To add, I am only returning after clean has run in order to give the user all errors at once. I did not feel that returning after each found error was a good user experience

It's good practice to provide your code to help people see what you are doing. This includes your error reports/traceback info. Use the markdown options to help make your post more readable.
I could be wrong but from my own experience, I usually clean each field individually as per the documentation unless they rely on each other such as passwords, etc.
you can read this part of the documentation to help get some clarity:
https://docs.djangoproject.com/en/1.10/ref/forms/validation/#cleaning-a-specific-field-attribute

Related

Getting KeyError in my django code

I'm new to both Django and Python so please forgive me if I come off as annoying....I'm just very much misinformed!
Error Code: http://i.gyazo.com/68d88cabf536b129dc37cde6c3ae319c.png
I've googled about this 'KeyError' and it seems to be related to clean(). However, the example my lecturer gave me worked ok without it but when I tried to recreate what he gave me I kept getting this error.
A bit of info: I had originally had a ForeignKey for the user for each submission so I changed it to a simple form to fill in (not a permanent solution) but I still get a KeyError.
Here is my models, views and forms:
http://pastebin.com/rAX5PDHQ
Sorry if I left something out. I'll respond ASAP if you all need more info.
Again, sorry if this is a silly question. But I'm utterly lost to be honest.
Thank you!
PS Sorry I really tried the code formatting but I kept getting an error saying it was incorrect thought the preview said it was ok. And I can't post more than one link.
You don't have a field named user in your form. Try changing the relevant line to:
bd = BloodData (respondent=cd['respondent'],
in your "storeBloodData" view.
The problem seems to be in your view storeBloodData,at this point.
bd = BloodData (respondent=cd['user'],
The form has no field named 'user'.You may replace it with a relevant field present declared in the form.
Also, it is better to use DICT.get(key)when you are not sure if the dict contains that particular key or not. This way you'll simply be returned None when the key is absent and you'll be able to dodge KeyError.

Wagtail/Django: This page could not be created due to validation errors

I have a little side project I'm working on that documents the history of racehorses, using Wagtail, a fairly new Django CMS.
One of my model classes that I'm using for it (Gist of it is here) keeps encountering the above error. I'm fairly sure it's one of the foreign key lines, as none of my other models have the same problem, but as my Django experience is limited I can't seem to determine what in particular is throwing the error.
My question is this. Is there anything from the above code that I'm obviously doing wrong? And further to that, are there any good resources that deal with model validation in particular?
You have 'intro' and 'biography' as required fields (i.e. there is no blank=True flag set on them), but there is no panel for them in content_panels. As a result, these fields will be throwing a "this field cannot be blank" validation error, but there's no place to display it on the form.

Django MVT design: Should I have all the code in models or views?

I'm pretty novice so I'll try to explain in a way that you can understand what I mean.
I'm coding a simple application in Django to track cash operations, track amounts, etc.
So I have an Account Model (with an amount field to track how many money is inside) and an Operation Model(with an amount field as well).
I've created a model helper called Account.add_operation(amount). Here is my question:
Should I include inside the code to create the new Operation inside Account.add_operation(amount) or should I do it in the Views?
And, should I call the save() method in the models (for example at the end of Account.add_operation() or must it be called in the views?)
What's the best approach, to have code inside the models or inside the views?
Thanks for your attention and your patience.
maybe you could use the rule "skinny controllers, fat models" to decide. Well in django it would be "skinny views".
To save related objects, in your case Operation I'd do it in the save() method or use the pre_save signal
Hope this helps
Experienced Django users seem to always err on the side of putting code in models. In part, that's because it's a lot easier to unit test models - they're usually pretty self-contained, whereas views touch both models and templates.
Beyond that, I would just ask yourself if the code pertains to the model itself or whether it's specific to the way it's being accessed and presented in a given view. I don't entirely understand your example (I think you're going to have to post some code if you want more specific help), but everything you mention sounds to me like it belongs in the model. That is, creating a new Operation sounds like it's an inherent part of what it means to do something called add_operation()!

Is Django's update_object generic view secure? Should I extend it or make my own for security?

I'm new to Django. Last night I worked hard on a view that would allow me to edit any of the entities in my current project; Chapters, Stories, and Worlds. In order to ensure that I know precisely which database object is being modified, I added a database entry to the tables 'edits' that stores the hash, the type of object being edited (eg. 'Chapter'), and the id of that object as found in the database. The hash is added to the form as a hidden input.
On the back-end, after the form has been submitted, I grab the hash and use it to find the related Edit item in the database. I then use this to find which object was initially being edited. This was done for two reasons:
I can know what object is truly being edited. If all form items have changed, there would be nothing to compare to (except URLs) to actually know which object is being edited.
Users should be unable to hack the front-end to do weird things like modify the wrong stories.
Today I discovered that Django has a generic view called update_object. This seems to handle a lot of things for me. But given that it doesn't automatically use the database to ensure that the correct object is being edited, or even determine which object is being edited, is this secure? surely there must be a simple way to hack it on the front end by modifying HTML elements.
Secondly, if this should be a concern, would you recommend that I keep my own edit view, or that I extend the update_object view, or some other solution?
Lastly, am I going about this the right way at all? Please correct me if I'm not thinking about solutions to this problem in the right way.
I don't feel that this is a question that requires code. It's more of a general question about the security of forms as they pertain to Django.
Thanks,
ParagonRG
Your problem of knowing which object they're editing is typically solved either by inspecting the URL or by a hidden form element that just has the database ID.
Before accepting any changes from a user form, you should be verifying that the user has permission to do whatever it is they're asking to be doing, and that the edits make sense. You'd normally do this with form validators and/or explicit checks in the view. This is a somewhat safer way of dealing with this problem, because it guarantees people aren't making DB changes they're not allowed to be making, whereas in your Edit object approach it's conceivable they could get around that.
If you take this approach, I don't see any reason why it's a problem that the user could be editing hidden ID fields to pretend to be editing a different object. They're just using a silly roundabout way to edit things when they could have just gone to a different edit link.
(Also: if you're using Django 1.3+, it's better to use the new class-based UpdateView rather than the function-based update_object.)

Display custom labels for values in the Django Admin Site

One of my models has a 'status' field which is only ever modified in code. It is an integer from 1 to 6 (although this may change in the future).
However, in the Admin site, I would like to display a label for this data. So, instead of displaying '5', I would like it to say 'Error'. This means I would be able to easily filter the objects in the database that have the status 'Error' and also my colleagues who don't know what each status means as they are not involved in coding, can use the admin site to its full.
I don't know if I am going the right way about this or if it is even possible, but I would appreciate any help you can give. I would rather not change how the status is stored as it would require a big re-write of some parts of our system. In hindsight I guess it was a bad way to do it, but I didn't think the field would matter as much as it does.
Consider to use choices. Anyway you can customize lots of things in django-admin, just read the docs:
http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
You could create a custom field type that overrides to_python and get_prep_value to store integers in the db but use string values within Python:
http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#django.db.models.django.db.models.Field

Categories

Resources