本文整理汇总了Python中rest_framework.utils.model_meta.get_field_info函数的典型用法代码示例。如果您正苦于以下问题:Python get_field_info函数的具体用法?Python get_field_info怎么用?Python get_field_info使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了get_field_info函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: validate
def validate(self, attrs):
# Since DRF 3.0 the model clean() method is no longer called
# automatically. And this is probably not the best solution to do the
# validation, but at the moment it's the simplest one.
if self.instance is None:
lsr = attrs.pop('lsr', None)
instance = WebHookMapping(**attrs)
instance.clean()
if lsr is not None:
attrs['lsr'] = lsr
else:
info = model_meta.get_field_info(self.instance)
for attr, value in attrs.items():
if attr == 'lsr':
# lsr can not be set directly at the moment, so skip it
continue
if attr in info.relations and info.relations[attr].to_many:
# We don't have any to-many relations at the moment, but
# this is to avoid setting them in the future if they are
# added. Manipulating to-many relation directly changes
# the DB so it can't be done here.
continue
else:
setattr(self.instance, attr, value)
self.instance.clean()
return attrs
示例2: _create
def _create(self, validated_data):
validated_data = validated_data.copy() # We're going to pop stuff off here.
# This logic is mostly copied from super().create(),
# aside from the concrete_data stuff and `.clean()`ing the model before saving.
ModelClass = self.Meta.model
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_data):
many_to_many[field_name] = validated_data.pop(field_name)
# Build a dict of fields we're guaranteed to be able to pass to `Model.create()`
concrete_fields = set(info.fields) | set(info.forward_relations)
concrete_data = {
field: value
for (field, value)
in validated_data.items()
if field in concrete_fields
}
instance = ModelClass(**concrete_data)
instance.clean()
instance.save()
for field_name, value in many_to_many.items():
setattr(instance, field_name, value)
return instance
示例3: create
def create(self, validated_data):
ModelClass = self.Meta.model
# Remove many-to-many relationships from validated_data.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_data):
many_to_many[field_name] = validated_data.pop(field_name)
try:
instance = ModelClass.objects.create(**validated_data)
except TypeError as exc:
msg = (
"Got a `TypeError` when calling `%s.objects.create()`. "
"This may be because you have a writable field on the "
"serializer class that is not a valid argument to "
"`%s.objects.create()`. You may need to make the field "
"read-only, or override the %s.create() method to handle "
"this correctly.\nOriginal exception text was: %s."
% (ModelClass.__name__, ModelClass.__name__, self.__class__.__name__, exc)
)
raise TypeError(msg)
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
if field_name == "permissions":
value = self._get_or_create_permissons(value)
setattr(instance, field_name, value)
return instance
示例4: update_id_fields
def update_id_fields(self, fields):
if 'id' not in self.fields:
conf = get_ct(self.Meta.model).get_config() or {}
lookup = conf.get('lookup', None)
if lookup and lookup != 'id':
fields['id'] = serializers.ReadOnlyField(source=lookup)
info = model_meta.get_field_info(self.Meta.model)
# In list views, remove [fieldname] as an attribute in favor of
# [fieldname]_id.
for name, field in info.forward_relations.items():
include = getattr(self.Meta, "fields", [])
exclude = getattr(self.Meta, "exclude", [])
if name in exclude or (include and name not in include):
fields.pop(name, None)
continue
id_field, id_field_kwargs = self.build_relational_field(
name, field
)
id_field_kwargs['source'] = name
fields[name + '_id'] = id_field(**id_field_kwargs)
if name in fields:
# Update/remove DRF default foreign key field (w/o _id)
if self.is_detail and isinstance(
fields[name], serializers.Serializer):
# Nested representation, keep for detail template context
fields[name].read_only = True
else:
# Otherwise we don't need this field
del fields[name]
return fields
示例5: equal_to_current
def equal_to_current(cls, json, fields_to_ignore=("id", "change_date", "changed_by")):
"""
Compares for equality this instance to a model instance constructed from the supplied JSON.
This will ignore any fields in `fields_to_ignore`.
Note that this method cannot handle fields with many-to-many associations, as those can only
be set on a saved model instance (and saving the model instance will create a new entry).
All many-to-many field entries will be removed before the equality comparison is done.
Args:
json: json representing an entry to compare
fields_to_ignore: List of fields that should not be compared for equality. By default
includes `id`, `change_date`, and `changed_by`.
Returns: True if the checked fields are all equivalent, else False
"""
# Remove many-to-many relationships from json.
# They require an instance to be already saved.
info = model_meta.get_field_info(cls)
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in json):
json.pop(field_name)
new_instance = cls(**json)
key_field_args = tuple(getattr(new_instance, key) for key in cls.KEY_FIELDS)
current = cls.current(*key_field_args)
# If current.id is None, no entry actually existed and the "current" method created it.
if current.id is not None:
return current.fields_equal(new_instance, fields_to_ignore)
return False
示例6: create
def create(self, validated_attrs):
# Check that the user isn't trying to handle a writable nested field.
# If we don't do this explicitly they'd likely get a confusing
# error at the point of calling `Model.objects.create()`.
assert not any(
isinstance(field, BaseSerializer) and not field.read_only
for field in self.fields.values()
), (
'The `.create()` method does not suport nested writable fields '
'by default. Write an explicit `.create()` method for serializer '
'`%s.%s`, or set `read_only=True` on nested serializer fields.' %
(self.__class__.__module__, self.__class__.__name__)
)
ModelClass = self.Meta.model
# Remove many-to-many relationships from validated_attrs.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_attrs):
many_to_many[field_name] = validated_attrs.pop(field_name)
instance = ModelClass.objects.create(**validated_attrs)
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
setattr(instance, field_name, value)
return instance
示例7: _compare_objects
def _compare_objects(self, db_obj, api_obj, serializer=None):
"""
Compare two objects with eachother based on the fields of the API serializer.
"""
serializer = serializer if serializer else self.serializer_cls()
serializer_field_list = serializer.get_field_names(
serializer._declared_fields,
model_meta.get_field_info(self.model_cls)
)
model_field_list = self.model_cls._meta.get_all_field_names()
for field in serializer_field_list:
if field in model_field_list:
# Make sure the field is in the response
self.assertIn(field, api_obj)
db_value = getattr(db_obj, field)
api_value = api_obj.get(field)
db_value = self._transform_value(db_value)
if isinstance(db_value, Model) or isinstance(db_value, Manager):
# Relationships can't be checked generically
continue
# Make sure the field value matches that of the factory object
self.assertEqual(api_value, db_value)
示例8: _configure_sideloads
def _configure_sideloads(self, meta):
"""
Assemble configuration for each sideload.
"""
self.sideloads = []
configs = []
for conf in getattr(meta, 'sideloads', []):
assert isinstance(conf, tuple) and len(conf) >= 2 \
and len(conf) <= 3, (
'`Meta.sideloads` must be a list of tuples in the following '
'format: (<model class>, <serializer class>, '
'<queryset instance (optional)>)'
)
model, serializer = conf[:2]
queryset = conf[0].objects.all() if (len(conf) == 2) else conf[2]
configs.append((model, serializer, queryset))
relations = get_field_info(self.model).relations
fields = self.base_serializer.fields.values()
for field_name, info in relations.items():
try:
conf = configs[[t[0] for t in configs].index(info.related)]
except ValueError:
continue
field = fields[[f.source for f in fields].index(field_name)]
key_name = getattr(conf[1].Meta, 'base_key',
underscore(conf[0].__name__))
self.sideloads.append(Sideload(
field=field, model=conf[0], serializer=conf[1],
queryset=conf[2], key_name=pluralize(key_name)
))
示例9: _filter_fields_by_permissions
def _filter_fields_by_permissions(self, fields, permissions_kind):
"""
Filter serializer fields by permissions kind
:param fields: serializer fields list
:param permissions_kind: edit/view
:return: fields allowed to interact with
"""
model = self.Meta.model
targets_map = {Permission.get_target(model, field): field for field in fields}
pk_fields = []
pk_target = Permission.get_target(model, 'pk')
if pk_target in targets_map:
pk_fields.append(targets_map.pop(pk_target))
pk_field = model_meta.get_field_info(model).pk
pk_target = Permission.get_target(model, pk_field)
if pk_target in targets_map:
pk_fields.append(targets_map.pop(pk_target))
allowed_targets = Permission.apply_permissions(self.permissions, targets_map.keys(), permissions_kind)
allowed_fields = list(map(lambda target: targets_map[target], allowed_targets))
if allowed_fields:
allowed_fields.extend(pk_fields)
return allowed_fields
示例10: _get_filter_strings_for_model
def _get_filter_strings_for_model(model, depth, exclude=[]):
info = model_meta.get_field_info(model)
# Add base fields
fields = info.fields.keys()
if depth > 0:
depth -= 1
# Add related fields one level deep
for field_name, rel in info.relations.iteritems():
# Will recursively add related fields according to value of `depth`
rel_field_names = [field_name + "__" + rel_field_name for rel_field_name in _get_filter_strings_for_model(rel.related_model, depth, exclude=exclude)]
rel_field_names.append(field_name)
fields += rel_field_names
# filters_for_model is used by django_filters to determine
# if fields we request to filter on are valid. So use that
# to silently pass out any fields which django_filters will
# complain about.
all_filters = filters_for_model(
model,
fields=fields,
exclude=exclude,
filter_for_field=FilterSet.filter_for_field,
filter_for_reverse_field=FilterSet.filter_for_reverse_field
)
tmp_fields = []
for f in fields:
if all_filters.get(f, False) == None:
continue
tmp_fields.append(f)
fields = tmp_fields
return fields
示例11: create
def create(self, validated_data):
"""
We have a bit of extra checking around this in order to provide
descriptive messages when something goes wrong, but this method is
essentially just:
return ExampleModel.objects.create(**validated_data)
If there are many to many fields present on the instance then they
cannot be set until the model is instantiated, in which case the
implementation is like so:
example_relationship = validated_data.pop('example_relationship')
instance = ExampleModel.objects.create(**validated_data)
instance.example_relationship = example_relationship
return instance
The default implementation also does not handle nested relationships.
If you want to support writable nested relationships you'll need
to write an explicit `.create()` method.
"""
raise_errors_on_nested_writes('create', self, validated_data)
ModelClass = self.Meta.model
# Remove many-to-many relationships from validated_data.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_data):
many_to_many[field_name] = validated_data.pop(field_name)
try:
instance = ModelClass.objects.create(**validated_data)
except TypeError as exc:
msg = (
'Got a `TypeError` when calling `%s.objects.create()`. '
'This may be because you have a writable field on the '
'serializer class that is not a valid argument to '
'`%s.objects.create()`. You may need to make the field '
'read-only, or override the %s.create() method to handle '
'this correctly.\nOriginal exception text was: %s.' %
(
ModelClass.__name__,
ModelClass.__name__,
self.__class__.__name__,
exc
)
)
raise TypeError(msg)
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
setattr(instance, field_name, value)
return instance
示例12: perform_update
def perform_update(self, serializer):
ModelClass = serializer.Meta.model
field_info = model_meta.get_field_info(ModelClass)
kwargs = {}
if 'last_updater' in field_info.relations:
kwargs['last_updater'] = self.request.user
instance = serializer.save(**kwargs)
if self._should_log_activity(instance):
self.make_log_activity(instance, CHANGE)
示例13: build_natural_key_fields
def build_natural_key_fields(self):
info = model_meta.get_field_info(self.Meta.model)
fields = OrderedDict()
for field, relation_info in info.relations.items():
if not issubclass(relation_info.related_model, NaturalKeyModel):
continue
field_class, field_kwargs = self.build_nested_field(
field, relation_info, 1
)
fields[field] = field_class(**field_kwargs)
return fields
示例14: update
def update(self, instance, validated_data):
#This is the same implementation as in ModelSerializer, but minus the assertion about nested writes!
info = model_meta.get_field_info(instance)
for attr, value in validated_data.items():
if attr in info.relations and info.relations[attr].to_many:
field = getattr(instance, attr)
field.set(value)
else:
setattr(instance, attr, value)
instance.save()
return instance
示例15: create
def create(self, validated_attrs):
"""
We have a bit of extra checking around this in order to provide
descriptive messages when something goes wrong, but this method is
essentially just:
return ExampleModel.objects.create(**validated_attrs)
If there are many to many fields present on the instance then they
cannot be set until the model is instantiated, in which case the
implementation is like so:
example_relationship = validated_attrs.pop('example_relationship')
instance = ExampleModel.objects.create(**validated_attrs)
instance.example_relationship = example_relationship
return instance
The default implementation also does not handle nested relationships.
If you want to support writable nested relationships you'll need
to write an explicit `.create()` method.
"""
# Check that the user isn't trying to handle a writable nested field.
# If we don't do this explicitly they'd likely get a confusing
# error at the point of calling `Model.objects.create()`.
assert not any(
isinstance(field, BaseSerializer) and not field.read_only
for field in self.fields.values()
), (
'The `.create()` method does not suport nested writable fields '
'by default. Write an explicit `.create()` method for serializer '
'`%s.%s`, or set `read_only=True` on nested serializer fields.' %
(self.__class__.__module__, self.__class__.__name__)
)
ModelClass = self.Meta.model
# Remove many-to-many relationships from validated_attrs.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_attrs):
many_to_many[field_name] = validated_attrs.pop(field_name)
instance = ModelClass.objects.create(**validated_attrs)
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
setattr(instance, field_name, value)
return instance