As pointed out in this answer, Django 1.9 added the Field.disabled attribute:
The disabled boolean argument, when set to True, disables a form field using the disabled HTML attribute so that it won’t be editable by users. Even if a user tampers with the field’s value submitted to the server, it will be ignored in favor of the value from the form’s initial data.
With Django 1.8 and earlier, to disable entry on the widget and prevent malicious POST hacks you must scrub the input in addition to setting the readonly
attribute on the form field:
class ItemForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ItemForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['sku'].widget.attrs['readonly'] = True
def clean_sku(self):
instance = getattr(self, 'instance', None)
if instance and instance.pk:
return instance.sku
else:
return self.cleaned_data['sku']
Or, replace if instance and instance.pk
with another condition indicating you're editing. You could also set the attribute disabled
on the input field, instead of readonly
.
The clean_sku
function will ensure that the readonly
value won't be overridden by a POST
.
Otherwise, there is no built-in Django form field which will render a value while rejecting bound input data. If this is what you desire, you should instead create a separate ModelForm
that excludes the uneditable field(s), and just print them inside your template.
MongoDB 2.2's new $elemMatch
projection operator provides another way to alter the returned document to contain only the first matched shapes
element:
db.test.find(
{"shapes.color": "red"},
{_id: 0, shapes: {$elemMatch: {color: "red"}}});
Returns:
{"shapes" : [{"shape": "circle", "color": "red"}]}
In 2.2 you can also do this using the $ projection operator
, where the $
in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:
db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});
MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new $filter
aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
{$match: {'shapes.color': 'red'}},
{$project: {
shapes: {$filter: {
input: '$shapes',
as: 'shape',
cond: {$eq: ['$$shape.color', 'red']}
}},
_id: 0
}}
])
Results:
[
{
"shapes" : [
{
"shape" : "circle",
"color" : "red"
}
]
}
]
Best Answer
Same as the updating existing collection field,
$set
will add a new fields if the specified field does not exist.Check out this example:
EDIT:
In case you want to add a new_field to all your collection, you have to use empty selector, and set multi flag to true (last param) to update all the documents
EDIT:
In the above example last 2 fields
false, true
specifies theupsert
andmulti
flags.Upsert: If set to true, creates a new document when no document matches the query criteria.
Multi: If set to true, updates multiple documents that meet the query criteria. If set to false, updates one document.
This is for Mongo
versions
prior to2.2
. For latest versions the query is changed a bit