diff options
author | CoprDistGit <infra@openeuler.org> | 2023-04-11 10:27:29 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-04-11 10:27:29 +0000 |
commit | 874c9f616dbc5e21d3ead991e8e2af47d417bc03 (patch) | |
tree | 3aae925741edccc4a2776059eea62f0c2f8faab5 | |
parent | ddb4be0c55a962ccf70a0db38cc927813bf63f43 (diff) |
automatic import of python-rest-framework-generic-relations
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-rest-framework-generic-relations.spec | 757 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 759 insertions, 0 deletions
@@ -0,0 +1 @@ +/rest-framework-generic-relations-2.1.0.tar.gz diff --git a/python-rest-framework-generic-relations.spec b/python-rest-framework-generic-relations.spec new file mode 100644 index 0000000..53b8171 --- /dev/null +++ b/python-rest-framework-generic-relations.spec @@ -0,0 +1,757 @@ +%global _empty_manifest_terminate_build 0 +Name: python-rest-framework-generic-relations +Version: 2.1.0 +Release: 1 +Summary: Generic Relations for Django Rest Framework +License: BSD +URL: https://github.com/Ian-Foote/rest-framework-generic-relations +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/34/cc/14cdd051e5fcda93d92325a83952e43de3c707ca48e290f66607f73d0462/rest-framework-generic-relations-2.1.0.tar.gz +BuildArch: noarch + +Requires: python3-djangorestframework + +%description +# Rest Framework Generic Relations [](https://github.com/Ian-Foote/rest-framework-generic-relations/actions/workflows/tests.yml) + + +This library implements [Django REST Framework](http://www.django-rest-framework.org/) serializers to handle generic foreign keys. + +# Requirements + +Any currently-supported combination of Django REST Framework, Python, and Django. + +# Installation + +Install using `pip`... +```sh +pip install rest-framework-generic-relations +``` +Add `'generic_relations'` to your `INSTALLED_APPS` setting. +```python +INSTALLED_APPS = ( + ... + 'generic_relations', +) +``` + + +# API Reference + +## GenericRelatedField + +This field serializes generic foreign keys. For a primer on generic foreign keys, first see: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ + + +Let's assume a `TaggedItem` model which has a generic relationship with other arbitrary models: + +```python +class TaggedItem(models.Model): + tag_name = models.SlugField() + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + tagged_object = GenericForeignKey('content_type', 'object_id') +``` + +And the following two models, which may have associated tags: + +```python +class Bookmark(models.Model): + """ + A bookmark consists of a URL, and 0 or more descriptive tags. + """ + url = models.URLField() + tags = GenericRelation(TaggedItem) + +class Note(models.Model): + """ + A note consists of some text, and 0 or more descriptive tags. + """ + text = models.CharField(max_length=1000) + tags = GenericRelation(TaggedItem) +``` + +Now we define serializers for each model that may get associated with tags. + +```python +class BookmarkSerializer(serializers.ModelSerializer): + class Meta: + model = Bookmark + fields = ('url',) + +class NoteSerializer(serializers.ModelSerializer): + class Meta: + model = Note + fields = ('text',) +``` + +The model serializer for the `TaggedItem` model could look like this: + +```python +from generic_relations.relations import GenericRelatedField + +class TagSerializer(serializers.ModelSerializer): + """ + A `TaggedItem` serializer with a `GenericRelatedField` mapping all possible + models to their respective serializers. + """ + tagged_object = GenericRelatedField({ + Bookmark: BookmarkSerializer(), + Note: NoteSerializer() + }) + + class Meta: + model = TaggedItem + fields = ('tag_name', 'tagged_object') +``` + +The JSON representation of a `TaggedItem` object with `name='django'` and its generic foreign key pointing at a `Bookmark` object with `url='https://www.djangoproject.com/'` would look like this: + +```json +{ + "tagged_object": { + "url": "https://www.djangoproject.com/" + }, + "tag_name": "django" +} +``` + +If you want to have your generic foreign key represented as hyperlink, simply use `HyperlinkedRelatedField` objects: + +```python +class TagSerializer(serializers.ModelSerializer): + """ + A `Tag` serializer with a `GenericRelatedField` mapping all possible + models to properly set up `HyperlinkedRelatedField`s. + """ + tagged_object = GenericRelatedField({ + Bookmark: serializers.HyperlinkedRelatedField( + queryset = Bookmark.objects.all(), + view_name='bookmark-detail', + ), + Note: serializers.HyperlinkedRelatedField( + queryset = Note.objects.all(), + view_name='note-detail', + ), + }) + + class Meta: + model = TaggedItem + fields = ('tag_name', 'tagged_object') +``` + +The JSON representation of the same `TaggedItem` example object could now look something like this: + +```json +{ + "tagged_object": "/bookmark/1/", + "tag_name": "django" +} +``` + +## Writing to generic foreign keys + +The above `TagSerializer` is also writable. By default, a `GenericRelatedField` iterates over its nested serializers and returns the value of the first serializer that is actually able to perform `to_internal_value()` without any errors. +Note, that (at the moment) only `HyperlinkedRelatedField` is able to serialize model objects out of the box. + + +The following operations would create a `TaggedItem` object with it's `tagged_object` property pointing at the `Bookmark` object found at the given detail end point. + +```python +tag_serializer = TagSerializer(data={ + 'tag_name': 'python', + 'tagged_object': '/bookmark/1/' +}) + +tag_serializer.is_valid() +tag_serializer.save() +``` + +If you feel that this default behavior doesn't suit your needs, you can subclass `GenericRelatedField` and override its `get_serializer_for_instance` or `get_deserializer_for_data` respectively to implement your own way of decision-making. + +## GenericModelSerializer + +Sometimes you may want to serialize a single list of different top-level things. For instance, suppose I have an API view that returns what items are on my bookshelf. Let's define some models: + +```python +from django.core.validators import MaxValueValidator + +class Book(models.Model): + title = models.CharField(max_length=255) + author = models.CharField(max_length=255) + +class Bluray(models.Model): + title = models.CharField(max_length=255) + rating = models.PositiveSmallIntegerField( + validators=[MaxValueValidator(5)], + ) +``` + +Then we could have a serializer for each type of object: + +```python +class BookSerializer(serializers.ModelSerializer): + class Meta: + model = Book + fields = ('title', 'author') + +class BluraySerializer(serializers.ModelSerializer): + class Meta: + model = Bluray + fields = ('title', 'rating') +``` + +Now we can create a generic list serializer, which delegates to the above serializers based on the type of model it's serializing: + +```python +bookshelf_item_serializer = GenericModelSerializer( + { + Book: BookSerializer(), + Bluray: BluraySerializer(), + }, + many=True, +) +``` + +Then we can serialize a mixed list of items: + +```python +>>> bookshelf_item_serializer.to_representation([ + Book.objects.get(title='War and Peace'), + Bluray.objects.get(title='Die Hard'), + Bluray.objects.get(title='Shawshank Redemption'), + Book.objects.get(title='To Kill a Mockingbird'), +]) + +[ + {'title': 'War and Peace', 'author': 'Leo Tolstoy'}, + {'title': 'Die Hard', 'rating': 5}, + {'title': 'Shawshank Redemption', 'rating': 5}, + {'title': 'To Kill a Mockingbird', 'author': 'Harper Lee'} +] +``` + + +## A few things you should note: + +* Although `GenericForeignKey` fields can be set to any model object, the `GenericRelatedField` only handles models explicitly defined in its configuration dictionary. +* Reverse generic keys, expressed using the `GenericRelation` field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known. +* The order in which you register serializers matters as far as write operations are concerned. +* Unless you provide a custom `get_deserializer_for_data()` method, only `HyperlinkedRelatedField` provides write access to generic model relations. + + + + +%package -n python3-rest-framework-generic-relations +Summary: Generic Relations for Django Rest Framework +Provides: python-rest-framework-generic-relations +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-rest-framework-generic-relations +# Rest Framework Generic Relations [](https://github.com/Ian-Foote/rest-framework-generic-relations/actions/workflows/tests.yml) + + +This library implements [Django REST Framework](http://www.django-rest-framework.org/) serializers to handle generic foreign keys. + +# Requirements + +Any currently-supported combination of Django REST Framework, Python, and Django. + +# Installation + +Install using `pip`... +```sh +pip install rest-framework-generic-relations +``` +Add `'generic_relations'` to your `INSTALLED_APPS` setting. +```python +INSTALLED_APPS = ( + ... + 'generic_relations', +) +``` + + +# API Reference + +## GenericRelatedField + +This field serializes generic foreign keys. For a primer on generic foreign keys, first see: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ + + +Let's assume a `TaggedItem` model which has a generic relationship with other arbitrary models: + +```python +class TaggedItem(models.Model): + tag_name = models.SlugField() + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + tagged_object = GenericForeignKey('content_type', 'object_id') +``` + +And the following two models, which may have associated tags: + +```python +class Bookmark(models.Model): + """ + A bookmark consists of a URL, and 0 or more descriptive tags. + """ + url = models.URLField() + tags = GenericRelation(TaggedItem) + +class Note(models.Model): + """ + A note consists of some text, and 0 or more descriptive tags. + """ + text = models.CharField(max_length=1000) + tags = GenericRelation(TaggedItem) +``` + +Now we define serializers for each model that may get associated with tags. + +```python +class BookmarkSerializer(serializers.ModelSerializer): + class Meta: + model = Bookmark + fields = ('url',) + +class NoteSerializer(serializers.ModelSerializer): + class Meta: + model = Note + fields = ('text',) +``` + +The model serializer for the `TaggedItem` model could look like this: + +```python +from generic_relations.relations import GenericRelatedField + +class TagSerializer(serializers.ModelSerializer): + """ + A `TaggedItem` serializer with a `GenericRelatedField` mapping all possible + models to their respective serializers. + """ + tagged_object = GenericRelatedField({ + Bookmark: BookmarkSerializer(), + Note: NoteSerializer() + }) + + class Meta: + model = TaggedItem + fields = ('tag_name', 'tagged_object') +``` + +The JSON representation of a `TaggedItem` object with `name='django'` and its generic foreign key pointing at a `Bookmark` object with `url='https://www.djangoproject.com/'` would look like this: + +```json +{ + "tagged_object": { + "url": "https://www.djangoproject.com/" + }, + "tag_name": "django" +} +``` + +If you want to have your generic foreign key represented as hyperlink, simply use `HyperlinkedRelatedField` objects: + +```python +class TagSerializer(serializers.ModelSerializer): + """ + A `Tag` serializer with a `GenericRelatedField` mapping all possible + models to properly set up `HyperlinkedRelatedField`s. + """ + tagged_object = GenericRelatedField({ + Bookmark: serializers.HyperlinkedRelatedField( + queryset = Bookmark.objects.all(), + view_name='bookmark-detail', + ), + Note: serializers.HyperlinkedRelatedField( + queryset = Note.objects.all(), + view_name='note-detail', + ), + }) + + class Meta: + model = TaggedItem + fields = ('tag_name', 'tagged_object') +``` + +The JSON representation of the same `TaggedItem` example object could now look something like this: + +```json +{ + "tagged_object": "/bookmark/1/", + "tag_name": "django" +} +``` + +## Writing to generic foreign keys + +The above `TagSerializer` is also writable. By default, a `GenericRelatedField` iterates over its nested serializers and returns the value of the first serializer that is actually able to perform `to_internal_value()` without any errors. +Note, that (at the moment) only `HyperlinkedRelatedField` is able to serialize model objects out of the box. + + +The following operations would create a `TaggedItem` object with it's `tagged_object` property pointing at the `Bookmark` object found at the given detail end point. + +```python +tag_serializer = TagSerializer(data={ + 'tag_name': 'python', + 'tagged_object': '/bookmark/1/' +}) + +tag_serializer.is_valid() +tag_serializer.save() +``` + +If you feel that this default behavior doesn't suit your needs, you can subclass `GenericRelatedField` and override its `get_serializer_for_instance` or `get_deserializer_for_data` respectively to implement your own way of decision-making. + +## GenericModelSerializer + +Sometimes you may want to serialize a single list of different top-level things. For instance, suppose I have an API view that returns what items are on my bookshelf. Let's define some models: + +```python +from django.core.validators import MaxValueValidator + +class Book(models.Model): + title = models.CharField(max_length=255) + author = models.CharField(max_length=255) + +class Bluray(models.Model): + title = models.CharField(max_length=255) + rating = models.PositiveSmallIntegerField( + validators=[MaxValueValidator(5)], + ) +``` + +Then we could have a serializer for each type of object: + +```python +class BookSerializer(serializers.ModelSerializer): + class Meta: + model = Book + fields = ('title', 'author') + +class BluraySerializer(serializers.ModelSerializer): + class Meta: + model = Bluray + fields = ('title', 'rating') +``` + +Now we can create a generic list serializer, which delegates to the above serializers based on the type of model it's serializing: + +```python +bookshelf_item_serializer = GenericModelSerializer( + { + Book: BookSerializer(), + Bluray: BluraySerializer(), + }, + many=True, +) +``` + +Then we can serialize a mixed list of items: + +```python +>>> bookshelf_item_serializer.to_representation([ + Book.objects.get(title='War and Peace'), + Bluray.objects.get(title='Die Hard'), + Bluray.objects.get(title='Shawshank Redemption'), + Book.objects.get(title='To Kill a Mockingbird'), +]) + +[ + {'title': 'War and Peace', 'author': 'Leo Tolstoy'}, + {'title': 'Die Hard', 'rating': 5}, + {'title': 'Shawshank Redemption', 'rating': 5}, + {'title': 'To Kill a Mockingbird', 'author': 'Harper Lee'} +] +``` + + +## A few things you should note: + +* Although `GenericForeignKey` fields can be set to any model object, the `GenericRelatedField` only handles models explicitly defined in its configuration dictionary. +* Reverse generic keys, expressed using the `GenericRelation` field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known. +* The order in which you register serializers matters as far as write operations are concerned. +* Unless you provide a custom `get_deserializer_for_data()` method, only `HyperlinkedRelatedField` provides write access to generic model relations. + + + + +%package help +Summary: Development documents and examples for rest-framework-generic-relations +Provides: python3-rest-framework-generic-relations-doc +%description help +# Rest Framework Generic Relations [](https://github.com/Ian-Foote/rest-framework-generic-relations/actions/workflows/tests.yml) + + +This library implements [Django REST Framework](http://www.django-rest-framework.org/) serializers to handle generic foreign keys. + +# Requirements + +Any currently-supported combination of Django REST Framework, Python, and Django. + +# Installation + +Install using `pip`... +```sh +pip install rest-framework-generic-relations +``` +Add `'generic_relations'` to your `INSTALLED_APPS` setting. +```python +INSTALLED_APPS = ( + ... + 'generic_relations', +) +``` + + +# API Reference + +## GenericRelatedField + +This field serializes generic foreign keys. For a primer on generic foreign keys, first see: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ + + +Let's assume a `TaggedItem` model which has a generic relationship with other arbitrary models: + +```python +class TaggedItem(models.Model): + tag_name = models.SlugField() + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + tagged_object = GenericForeignKey('content_type', 'object_id') +``` + +And the following two models, which may have associated tags: + +```python +class Bookmark(models.Model): + """ + A bookmark consists of a URL, and 0 or more descriptive tags. + """ + url = models.URLField() + tags = GenericRelation(TaggedItem) + +class Note(models.Model): + """ + A note consists of some text, and 0 or more descriptive tags. + """ + text = models.CharField(max_length=1000) + tags = GenericRelation(TaggedItem) +``` + +Now we define serializers for each model that may get associated with tags. + +```python +class BookmarkSerializer(serializers.ModelSerializer): + class Meta: + model = Bookmark + fields = ('url',) + +class NoteSerializer(serializers.ModelSerializer): + class Meta: + model = Note + fields = ('text',) +``` + +The model serializer for the `TaggedItem` model could look like this: + +```python +from generic_relations.relations import GenericRelatedField + +class TagSerializer(serializers.ModelSerializer): + """ + A `TaggedItem` serializer with a `GenericRelatedField` mapping all possible + models to their respective serializers. + """ + tagged_object = GenericRelatedField({ + Bookmark: BookmarkSerializer(), + Note: NoteSerializer() + }) + + class Meta: + model = TaggedItem + fields = ('tag_name', 'tagged_object') +``` + +The JSON representation of a `TaggedItem` object with `name='django'` and its generic foreign key pointing at a `Bookmark` object with `url='https://www.djangoproject.com/'` would look like this: + +```json +{ + "tagged_object": { + "url": "https://www.djangoproject.com/" + }, + "tag_name": "django" +} +``` + +If you want to have your generic foreign key represented as hyperlink, simply use `HyperlinkedRelatedField` objects: + +```python +class TagSerializer(serializers.ModelSerializer): + """ + A `Tag` serializer with a `GenericRelatedField` mapping all possible + models to properly set up `HyperlinkedRelatedField`s. + """ + tagged_object = GenericRelatedField({ + Bookmark: serializers.HyperlinkedRelatedField( + queryset = Bookmark.objects.all(), + view_name='bookmark-detail', + ), + Note: serializers.HyperlinkedRelatedField( + queryset = Note.objects.all(), + view_name='note-detail', + ), + }) + + class Meta: + model = TaggedItem + fields = ('tag_name', 'tagged_object') +``` + +The JSON representation of the same `TaggedItem` example object could now look something like this: + +```json +{ + "tagged_object": "/bookmark/1/", + "tag_name": "django" +} +``` + +## Writing to generic foreign keys + +The above `TagSerializer` is also writable. By default, a `GenericRelatedField` iterates over its nested serializers and returns the value of the first serializer that is actually able to perform `to_internal_value()` without any errors. +Note, that (at the moment) only `HyperlinkedRelatedField` is able to serialize model objects out of the box. + + +The following operations would create a `TaggedItem` object with it's `tagged_object` property pointing at the `Bookmark` object found at the given detail end point. + +```python +tag_serializer = TagSerializer(data={ + 'tag_name': 'python', + 'tagged_object': '/bookmark/1/' +}) + +tag_serializer.is_valid() +tag_serializer.save() +``` + +If you feel that this default behavior doesn't suit your needs, you can subclass `GenericRelatedField` and override its `get_serializer_for_instance` or `get_deserializer_for_data` respectively to implement your own way of decision-making. + +## GenericModelSerializer + +Sometimes you may want to serialize a single list of different top-level things. For instance, suppose I have an API view that returns what items are on my bookshelf. Let's define some models: + +```python +from django.core.validators import MaxValueValidator + +class Book(models.Model): + title = models.CharField(max_length=255) + author = models.CharField(max_length=255) + +class Bluray(models.Model): + title = models.CharField(max_length=255) + rating = models.PositiveSmallIntegerField( + validators=[MaxValueValidator(5)], + ) +``` + +Then we could have a serializer for each type of object: + +```python +class BookSerializer(serializers.ModelSerializer): + class Meta: + model = Book + fields = ('title', 'author') + +class BluraySerializer(serializers.ModelSerializer): + class Meta: + model = Bluray + fields = ('title', 'rating') +``` + +Now we can create a generic list serializer, which delegates to the above serializers based on the type of model it's serializing: + +```python +bookshelf_item_serializer = GenericModelSerializer( + { + Book: BookSerializer(), + Bluray: BluraySerializer(), + }, + many=True, +) +``` + +Then we can serialize a mixed list of items: + +```python +>>> bookshelf_item_serializer.to_representation([ + Book.objects.get(title='War and Peace'), + Bluray.objects.get(title='Die Hard'), + Bluray.objects.get(title='Shawshank Redemption'), + Book.objects.get(title='To Kill a Mockingbird'), +]) + +[ + {'title': 'War and Peace', 'author': 'Leo Tolstoy'}, + {'title': 'Die Hard', 'rating': 5}, + {'title': 'Shawshank Redemption', 'rating': 5}, + {'title': 'To Kill a Mockingbird', 'author': 'Harper Lee'} +] +``` + + +## A few things you should note: + +* Although `GenericForeignKey` fields can be set to any model object, the `GenericRelatedField` only handles models explicitly defined in its configuration dictionary. +* Reverse generic keys, expressed using the `GenericRelation` field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known. +* The order in which you register serializers matters as far as write operations are concerned. +* Unless you provide a custom `get_deserializer_for_data()` method, only `HyperlinkedRelatedField` provides write access to generic model relations. + + + + +%prep +%autosetup -n rest-framework-generic-relations-2.1.0 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-rest-framework-generic-relations -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 2.1.0-1 +- Package Spec generated @@ -0,0 +1 @@ +24d50c03d867f10ea9882a66965b8a88 rest-framework-generic-relations-2.1.0.tar.gz |