Prevent Django model field from being rendered - django

I'm adding a per-user secret key to one of my Django models for internal usage, but I want to make sure that it is not accidentally exposed to the user. Obviously, I can check all the forms using that model today and ensure that they exclude the field, but that is not future proof. Is there any way I can mark a field so it is never rendered or sent to the client even if a form otherwise includes it?

You could use editable=False on your Model field as documented and here
If False, the field will not be displayed in the admin or any other
ModelForm. They are also skipped during model validation. Default is
True.
Note this works for ModelForms and if you are using regular Form you might consider extending it with custom implementation
ModelForm editable removal implementation source

Related

Why does BaseModelForm update ALL fields, despite documentation saying it does not? Is this a bug?

I'm working on a django project with a legacy DB, using formset to edit a set of rows. There are fields in that DB that I don't want django to update, although I need them in my model. In other words, I want them to be treated as READ-ONLY fields.
Thus, I was happy to read the documentation on saving model formsets, which states:
"When fields are missing from the form (for example because they have
been excluded), these fields will not be set by the save() method. You
can find more information about this restriction, which also holds for
regular ModelForms, in Selecting the fields to use."
https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#saving-objects-in-the-formset
Indeed, when forms.model.BaseModelForm.save() is invoked, it calls forms.model.save_instance(), nicely passing in all the form fields. BUT than then calls instance.save() WITHOUT passing along the update_fields!! And so ALL the model fields are included in the update query :-(
As a test, I modified forms.model.save_instance() to pass the fields:
instance.save(update_fields=fields)
and voila - the model only saves fields listed by its form.
I'm hoping someone more involved in the django project can tell me if this a bug, or a documentation issue? Should I submit a bug report? Am I missing something - is there some other way I should be enforcing "read only" on those fields?
Using django1.8 and python3.4
I'm not sure why you think this behaviour contradicts that documentation, or why it would need to pass along the fields to update. The instance already has the unchanged data; Django will update the rest of the fields from the form, and save the whole thing.

OnetoOne models not being saved when using default values

I have a model with default values defined. When a model is created as an inline in the administration backend and the default values remain unchanged, the model doesn't save, but if any field is altered, then the model will save.
I havent overridden any save or clean methods on the model or form.
Is this expected behavior?
The problem here is that Django is trying to see which inlines you actually want to save. As the docs put it: "The formset is smart enough to ignore extra forms that were not changed." So if you use all default values it thinks you're not using those inlines.
You could try using empty_permitted as described in this answer, although I don't think it's officially documented. You'll also have to be careful that the initial formset only includes (via extra) the minimum number of inlines you require.

When to use form vs model validation?

Just curious. What is the best practice for when to use form vs model validation?
From what I understand currently, form validation should be used for:
AJAX / HTTP requests params
Forms that do not correlate to a model?
Another question is: I have a HTML form that roughly correlates to a model instance, do I use a ModelForm for it?
Definitely use ModelForm, if your form resembles model object even in a tiny bit.
If there are some minor differences (e.g. you don't use some of the fields or you want to use different error messages etc.) it's much easier to customize ModelForm then to use Form and implement all this functionality from scratch.
For more reference regarding ModelForm please checkout PyDanny's Core Concepts of Django ModelForms.
I am also trying to understand what is the difference/relation between form and model validation and I would like to share my notes that are formed after reading several docs.
I am currently interested in Creating Forms from Models
#mariodev shared the document Core Concepts of Django ModelForms and this provided a good start.
ModelForms select validators based off of Model field definitions
The main story behind the scenes seems to be the DRY principal. This article explains very well what exactly is the case here.
All right, all this is fair. The question is "Where in the Django Documentation is this explained"?
I bumped on a very brilliant article where it states that:
The form.full_clean() method is called by django at the start of the validation process (by form.is_valid(), usually immediately after the view receives the posted data).
Correct me if I am wrong but that line reads that everytime I enter data and hit 'enter' the validation process begins!
OK, this is simple now:
The validation on a ModelForm begins when we hit 'enter'.
Django first validates the form by checking one by one every applicable validation method on Fields, Field Subclasses (This is the documentation for a model's field subclass, not for a form field subclass), Form Subclasses and ModelForm (since it is a ModelForm).
Finally, it validates the Model Instance.
This is how all this works theoretically. The only thing that remains is to implement it.

Blank, Null, and Required in Django Models and ModelForms

So far I haven't come across a clear explanation on blank, null, and required - in Django's models and forms.
I know the default for each is the following:
blank = False
null = False
required = True
I also know that:
blank=True (used in models.py), means on the form level, accept empty forms - the associated field is not required in a form.
null=True (used in models.py), means on the database level that Python None values can be stored in the model and be saved (and then end up as SQL NULL values in the database).
required=False (used in forms.py), means the associated form field is not required.
Hopefully the above information will serve others well (please let me know if there are any flaws in the logic, and I will update it).
My question is the following:
When do I know when to use blank=True vs. required=False. If my goal is to make a form field not required, I could define this in the model using blank=True, or I could define this in the form using required=False. Does this mean you can define blank=True in a model, and in the associated ModelForm override this with required=True?
Also related, what about when you are using a regular form (forms.Form)? Since the form is not associated with a model (other than through view logic), what happens if again, they contradict each other?
The contradictions don't matter. I think this brings flexibility to the development of a Django application. For example, if you're using a third party library that defines some models, and they set blank=True, but for other purposes you need that field is mandatory, then in your forms you can fix it without touching the third party library code.
This just add some flexibility to the framework IMHO, that brings no harm. You can use it for your own purposes. The contradictions are not significant.
Hope this helps!
It depends on the requirement. Sometime we decide later to make field mandatory on the form although on model it is still not required. But the form will ensure that field must be fill.
You can have null=True on the model and then later you can make that field mandatory on form. But you can not make a field optional in form when it is mandatory on model that will result in database error later on.

Django: what approaches are there to 'parametising' the display and editability of form fields.

Django: what approaches are there to 'parametising' the display and editability of form fields.
I have several forms where I want some fields to be simply missing from the form display (dependent on the current user) and some fields to be uneditable, depending on the user.
This needs to be enforced on the server, so that a malicious user cannot break the security by manually constructing a post request with the missing parameter.
Likewise fields which are not displayed to the user, must still come back in the form results, so that fields which are not displayed to a user and not 'wiped-out' when the model is written back to the DB.
I also need to solve the same hiding problem for templates.
The app will have dozens of forms, with different immutability/hiding requirements, so this needs to be a generic system. Coding permissions inside each form would be too prone to error.
Any help appreciated.
Chris.
For hidding fields from form display, simple delete unneeded fields in form's __init__ method. Constructing post request by adding deleted fields, will not have influence on the form.
Regarding disabled or readonly fields, check this article and another question. Basically, cleaning field should set it to initial state.