* Update relations.py
Currently if you define the slug field as a nested relationship in a `SlugRelatedField` while many=False, it will cause an attribute error. For example:
For this code:
```
class SomeSerializer(serializers.ModelSerializer):
some_field= serializers.SlugRelatedField(queryset=SomeClass.objects.all(), slug_field="foo__bar")
```
The POST request (or save operation) should work just fine, but if you use GET, then it will fail with Attribute error:
> AttributeError: 'SomeClass' object has no attribute 'foo__bar'
Thus I am handling nested relation here. Reference: https://stackoverflow.com/questions/75878103/drf-attributeerror-when-trying-to-creating-a-instance-with-slugrelatedfield-and/75882424#75882424
* Fixed test cases
* code comment changes related to slugrelatedfield
* changes based on pre-commit and removed comma which was added accidentally
* fixed primary keys of the mock object
* added more test cases based on review
---------
Co-authored-by: Arnab Shil <arnab.shil@thermofisher.com>
* Handle unset fields with 'many=True'
The docs note:
When serializing fields with dotted notation, it may be necessary to
provide a `default` value if any object is not present or is empty
during attribute traversal.
However, this doesn't work for fields with 'many=True'. When using
these, the default is simply ignored.
The solution is simple: do in 'ManyRelatedField' what we were already
doing for 'Field', namely, catch possible 'AttributeError' and
'KeyError' exceptions and return the default if there is one set.
Signed-off-by: Stephen Finucane <stephen@that.guru>
Closes: #7550
* Add test cases for #7550
Signed-off-by: Stephen Finucane <stephen@that.guru>
In the `to_internal_value` method of the primary key and slug related fields, `TypeError`s and `ValueError`s are caught from `self.get_queryset().get(...)` and presented to the user. This works fine for most cases, but can cause problems if the exception is coming from `self.get_queryset()` rather than from the `.get(...)`.
It means errors in the `get_queryset` method can be hidden and presented back to the user as though, for example, the input provided to the `to_internal_value` was the wrong type, whereas in reality there's a bug in the `get_queryset` method and therefore it should bubble up and be exposed as a server error.
I've decided to fix this because twice now I've had to debug why I'm seeing `invalid_type` errors from my serializer (errors like `wrong pk type - int` when the `pk` type on my model is `int`) when the real problem was a bug in my custom `get_queryset` method.
On Python 3, the ugettext functions are a simple aliases of their non-u
counterparts (the 'u' represents Python 2 unicode type). Starting with
Django 3.0, the u versions will be deprecated.
https://docs.djangoproject.com/en/dev/releases/3.0/#id2
> django.utils.translation.ugettext(), ugettext_lazy(), ugettext_noop(),
> ungettext(), and ungettext_lazy() are deprecated in favor of the
> functions that they’re aliases for:
> django.utils.translation.gettext(), gettext_lazy(), gettext_noop(),
> ngettext(), and ngettext_lazy().
Thanks to Jon Dufresne (@jdufresne) for review.
Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
Co-authored-by: Rizwan Mansuri <Rizwan@webbyfox.com>
As all source files import unicode_literals, type('') is always
equivalent to six.text_type (str on Python 3 and unicode on Python 2).
Removes the need to call type(), is more explicit, and will be easier to
catch places to change for when it is time to eventually drop Python 2.
Calling dict.keys() is unnecessary. The two are functionally equivalent
on modern Pythons.
Inspired by Lennart Regebro's talk "Prehistoric Patterns in Python" from
PyCon 2017.
https://www.youtube.com/watch?v=V5-JH23Vk0I
* Start test case
* Added 'requests' test client
* Address typos
* Graceful fallback if requests is not installed.
* Add cookie support
* Tests for auth and CSRF
* Py3 compat
* py3 compat
* py3 compat
* Add get_requests_client
* Added SchemaGenerator.should_include_link
* add settings for html cutoff on related fields
* Router doesn't work if prefix is blank, though project urls.py handles prefix
* Fix Django 1.10 to-many deprecation
* Add django.core.urlresolvers compatibility
* Update django-filter & django-guardian
* Check for empty router prefix; adjust URL accordingly
It's easiest to fix this issue after we have made the regex. To try
to fix it before would require doing something different for List vs
Detail, which means we'd have to know which type of url we're
constructing before acting accordingly.
* Fix misc django deprecations
* Use TOC extension instead of header
* Fix deprecations for py3k
* Add py3k compatibility to is_simple_callable
* Add is_simple_callable tests
* Drop python 3.2 support (EOL, Dropped by Django)
* schema_renderers= should *set* the renderers, not append to them.
* API client (#4424)
* Fix release notes
* Add note about 'User account is disabled.' vs 'Unable to log in'
* Clean up schema generation (#4527)
* Handle multiple methods on custom action (#4529)
* RequestsClient, CoreAPIClient
* exclude_from_schema
* Added 'get_schema_view()' shortcut
* Added schema descriptions
* Better descriptions for schemas
* Add type annotation to schema generation
* Coerce schema 'pk' in path to actual field name
* Deprecations move into assertion errors
* Use get_schema_view in tests
* Updte CoreJSON media type
* Handle schema structure correctly when path prefixs exist. Closes#4401
* Add PendingDeprecation to Router schema generation.
* Added SCHEMA_COERCE_PATH_PK and SCHEMA_COERCE_METHOD_NAMES
* Renamed and documented 'get_schema_fields' interface.
The user may wish to provide a dynamic queryset on a `RelatedField`
based on the `context`. The way to do that is to create a subclass of
`RelatedField` (or a child) and override the `get_queryset` method.
However, this is undocumented, and instantiating that field without a
`queryset` argument (because it's not needed) will raise an assertion
error.
Document `.get_queryset(self)` as an official part of the API of
`RelatedField`, and don't enforce the use of `queryset` when
`get_queryset` is overridden.
Returns the text representation of the instance. Subclasses can override this method to provide a different display value used for populating the `choices` property.