We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cleanup old publications - general cleanup
**Is your feature request related to a problem? Please describe.**
We do a lot of different new repos and publications - and also delete them after certain time.
Now i see, the publications resist.
Means, in normal handling we have hundreds of publications.
But, we don't know where they do belong to, becuase there is no name tag. 

**Describe the solution you'd like**
May be there is a possibility to remove old publications with no belonging or link to a repository or distribution. 

**Describe alternatives you've considered**
No idea, i just think about an clenaup job.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pulpcore/app/serializers/publication.py`
Content:
```
1 from gettext import gettext as _
2 
3 from django.core import validators
4 from django.db.models import Q
5 
6 from rest_framework import serializers
7 from rest_framework.validators import UniqueValidator
8 
9 from pulpcore.app import models
10 from pulpcore.app.serializers import (
11     BaseURLField,
12     DetailIdentityField,
13     DetailRelatedField,
14     NestedRelatedField,
15     RelatedField,
16     MasterModelSerializer,
17     ModelSerializer,
18     validate_unknown_fields,
19 )
20 
21 
22 class PublicationSerializer(MasterModelSerializer):
23     _href = DetailIdentityField()
24     repository_version = NestedRelatedField(
25         view_name='versions-detail',
26         lookup_field='number',
27         parent_lookup_kwargs={'repository_pk': 'repository__pk'},
28         queryset=models.RepositoryVersion.objects.all(),
29         required=False,
30     )
31     repository = serializers.HyperlinkedRelatedField(
32         help_text=_('A URI of the repository to be published.'),
33         required=False,
34         label=_('Repository'),
35         queryset=models.Repository.objects.all(),
36         view_name='repositories-detail',
37     )
38 
39     def validate(self, data):
40         if hasattr(self, 'initial_data'):
41             validate_unknown_fields(self.initial_data, self.fields)
42 
43         repository = data.pop('repository', None)  # not an actual field on publication
44         repository_version = data.get('repository_version')
45         if not repository and not repository_version:
46             raise serializers.ValidationError(
47                 _("Either the 'repository' or 'repository_version' need to be specified"))
48         elif not repository and repository_version:
49             return data
50         elif repository and not repository_version:
51             version = models.RepositoryVersion.latest(repository)
52             if version:
53                 new_data = {'repository_version': version}
54                 new_data.update(data)
55                 return new_data
56             else:
57                 raise serializers.ValidationError(
58                     detail=_('Repository has no version available to create Publication from'))
59         raise serializers.ValidationError(
60             _("Either the 'repository' or 'repository_version' need to be specified "
61               "but not both.")
62         )
63 
64     class Meta:
65         abstract = True
66         model = models.Publication
67         fields = MasterModelSerializer.Meta.fields + (
68             'publisher',
69             'repository_version',
70             'repository'
71         )
72 
73 
74 class ContentGuardSerializer(MasterModelSerializer):
75     _href = DetailIdentityField()
76 
77     name = serializers.CharField(
78         help_text=_('The unique name.')
79     )
80     description = serializers.CharField(
81         help_text=_('An optional description.'),
82         allow_blank=True,
83         required=False
84     )
85 
86     class Meta:
87         model = models.ContentGuard
88         fields = MasterModelSerializer.Meta.fields + (
89             'name',
90             'description'
91         )
92 
93 
94 class BaseDistributionSerializer(MasterModelSerializer):
95     _href = DetailIdentityField()
96     base_path = serializers.CharField(
97         help_text=_('The base (relative) path component of the published url. Avoid paths that \
98                     overlap with other distribution base paths (e.g. "foo" and "foo/bar")'),
99         validators=[validators.MaxLengthValidator(
100             models.BaseDistribution._meta.get_field('base_path').max_length,
101             message=_('`base_path` length must be less than {} characters').format(
102                 models.BaseDistribution._meta.get_field('base_path').max_length
103             )),
104             UniqueValidator(queryset=models.BaseDistribution.objects.all()),
105         ]
106     )
107     base_url = BaseURLField(
108         source='base_path', read_only=True,
109         help_text=_('The URL for accessing the publication as defined by this distribution.')
110     )
111     content_guard = DetailRelatedField(
112         required=False,
113         help_text=_('An optional content-guard.'),
114         queryset=models.ContentGuard.objects.all(),
115         allow_null=True
116     )
117     name = serializers.CharField(
118         help_text=_('A unique name. Ex, `rawhide` and `stable`.'),
119         validators=[validators.MaxLengthValidator(
120             models.BaseDistribution._meta.get_field('name').max_length,
121             message=_('`name` length must be less than {} characters').format(
122                 models.BaseDistribution._meta.get_field('name').max_length
123             )),
124             UniqueValidator(queryset=models.BaseDistribution.objects.all())]
125     )
126     remote = DetailRelatedField(
127         required=False,
128         help_text=_('Remote that can be used to fetch content when using pull-through caching.'),
129         queryset=models.Remote.objects.all(),
130         allow_null=True
131     )
132 
133     class Meta:
134         abstract = True
135         model = models.BaseDistribution
136         fields = ModelSerializer.Meta.fields + (
137             'base_path',
138             'base_url',
139             'content_guard',
140             'name',
141             'remote',
142         )
143 
144     def _validate_path_overlap(self, path):
145         # look for any base paths nested in path
146         search = path.split("/")[0]
147         q = Q(base_path=search)
148         for subdir in path.split("/")[1:]:
149             search = "/".join((search, subdir))
150             q |= Q(base_path=search)
151 
152         # look for any base paths that nest path
153         q |= Q(base_path__startswith='{}/'.format(path))
154         qs = models.BaseDistribution.objects.filter(q)
155 
156         if self.instance is not None:
157             qs = qs.exclude(pk=self.instance.pk)
158 
159         match = qs.first()
160         if match:
161             raise serializers.ValidationError(detail=_("Overlaps with existing distribution '"
162                                                        "{}'").format(match.name))
163 
164         return path
165 
166     def validate_base_path(self, path):
167         self._validate_relative_path(path)
168         return self._validate_path_overlap(path)
169 
170 
171 class PublicationDistributionSerializer(BaseDistributionSerializer):
172     publication = DetailRelatedField(
173         required=False,
174         help_text=_('Publication to be served'),
175         queryset=models.Publication.objects.exclude(complete=False),
176         allow_null=True
177     )
178 
179     class Meta:
180         abstract = True
181         fields = BaseDistributionSerializer.Meta.fields + (
182             'publication',
183         )
184 
185 
186 class RepositoryVersionDistributionSerializer(BaseDistributionSerializer):
187     repository = RelatedField(
188         required=False,
189         help_text=_('The latest RepositoryVersion for this Repository will be served.'),
190         queryset=models.Repository.objects.all(),
191         view_name='repositories-detail',
192         allow_null=True
193     )
194     repository_version = NestedRelatedField(
195         required=False,
196         help_text=_('RepositoryVersion to be served'),
197         queryset=models.RepositoryVersion.objects.exclude(complete=False),
198         view_name='versions-detail',
199         allow_null=True,
200         lookup_field='number',
201         parent_lookup_kwargs={'repository_pk': 'repository__pk'},
202     )
203 
204     class Meta:
205         abstract = True
206         fields = BaseDistributionSerializer.Meta.fields + (
207             'repository',
208             'repository_version',
209         )
210 
211     def validate(self, data):
212         super().validate(data)
213 
214         if 'repository' in data and 'repository_version' in data:
215             msg = _("The attributes 'repository' and 'repository_version' must be used"
216                     "exclusively.")
217             raise serializers.ValidationError(msg)
218 
219         return data
220
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pulpcore/app/serializers/publication.py b/pulpcore/app/serializers/publication.py
--- a/pulpcore/app/serializers/publication.py
+++ b/pulpcore/app/serializers/publication.py
@@ -92,6 +92,22 @@
 
 
 class BaseDistributionSerializer(MasterModelSerializer):
+    """
+    The Serializer for the BaseDistribution model.
+
+    The serializer deliberately omits the "remote" field, which is used for
+    pull-through caching only. Plugins implementing pull-through caching will
+    have to add the field in their derived serializer class like this::
+
+      remote = DetailRelatedField(
+          required=False,
+          help_text=_('Remote that can be used to fetch content when using pull-through caching.'),
+          queryset=models.Remote.objects.all(),
+          allow_null=True
+      )
+
+    """
+
     _href = DetailIdentityField()
     base_path = serializers.CharField(
         help_text=_('The base (relative) path component of the published url. Avoid paths that \
@@ -123,12 +139,6 @@
             )),
             UniqueValidator(queryset=models.BaseDistribution.objects.all())]
     )
-    remote = DetailRelatedField(
-        required=False,
-        help_text=_('Remote that can be used to fetch content when using pull-through caching.'),
-        queryset=models.Remote.objects.all(),
-        allow_null=True
-    )
 
     class Meta:
         abstract = True
@@ -138,7 +148,6 @@
             'base_url',
             'content_guard',
             'name',
-            'remote',
         )
 
     def _validate_path_overlap(self, path):

{"golden_diff": "diff --git a/pulpcore/app/serializers/publication.py b/pulpcore/app/serializers/publication.py\n--- a/pulpcore/app/serializers/publication.py\n+++ b/pulpcore/app/serializers/publication.py\n@@ -92,6 +92,22 @@\n \n \n class BaseDistributionSerializer(MasterModelSerializer):\n+    \"\"\"\n+    The Serializer for the BaseDistribution model.\n+\n+    The serializer deliberately omits the \"remote\" field, which is used for\n+    pull-through caching only. Plugins implementing pull-through caching will\n+    have to add the field in their derived serializer class like this::\n+\n+      remote = DetailRelatedField(\n+          required=False,\n+          help_text=_('Remote that can be used to fetch content when using pull-through caching.'),\n+          queryset=models.Remote.objects.all(),\n+          allow_null=True\n+      )\n+\n+    \"\"\"\n+\n     _href = DetailIdentityField()\n     base_path = serializers.CharField(\n         help_text=_('The base (relative) path component of the published url. Avoid paths that \\\n@@ -123,12 +139,6 @@\n             )),\n             UniqueValidator(queryset=models.BaseDistribution.objects.all())]\n     )\n-    remote = DetailRelatedField(\n-        required=False,\n-        help_text=_('Remote that can be used to fetch content when using pull-through caching.'),\n-        queryset=models.Remote.objects.all(),\n-        allow_null=True\n-    )\n \n     class Meta:\n         abstract = True\n@@ -138,7 +148,6 @@\n             'base_url',\n             'content_guard',\n             'name',\n-            'remote',\n         )\n \n     def _validate_path_overlap(self, path):\n", "issue": "Cleanup old publications - general cleanup\n**Is your feature request related to a problem? Please describe.**\r\nWe do a lot of different new repos and publications - and also delete them after certain time.\r\nNow i see, the publications resist.\r\nMeans, in normal handling we have hundreds of publications.\r\nBut, we don't know where they do belong to, becuase there is no name tag. \r\n\r\n**Describe the solution you'd like**\r\nMay be there is a possibility to remove old publications with no belonging or link to a repository or distribution. \r\n\r\n**Describe alternatives you've considered**\r\nNo idea, i just think about an clenaup job.\r\n\r\n\n", "before_files": [{"content": "from gettext import gettext as _\n\nfrom django.core import validators\nfrom django.db.models import Q\n\nfrom rest_framework import serializers\nfrom rest_framework.validators import UniqueValidator\n\nfrom pulpcore.app import models\nfrom pulpcore.app.serializers import (\n    BaseURLField,\n    DetailIdentityField,\n    DetailRelatedField,\n    NestedRelatedField,\n    RelatedField,\n    MasterModelSerializer,\n    ModelSerializer,\n    validate_unknown_fields,\n)\n\n\nclass PublicationSerializer(MasterModelSerializer):\n    _href = DetailIdentityField()\n    repository_version = NestedRelatedField(\n        view_name='versions-detail',\n        lookup_field='number',\n        parent_lookup_kwargs={'repository_pk': 'repository__pk'},\n        queryset=models.RepositoryVersion.objects.all(),\n        required=False,\n    )\n    repository = serializers.HyperlinkedRelatedField(\n        help_text=_('A URI of the repository to be published.'),\n        required=False,\n        label=_('Repository'),\n        queryset=models.Repository.objects.all(),\n        view_name='repositories-detail',\n    )\n\n    def validate(self, data):\n        if hasattr(self, 'initial_data'):\n            validate_unknown_fields(self.initial_data, self.fields)\n\n        repository = data.pop('repository', None)  # not an actual field on publication\n        repository_version = data.get('repository_version')\n        if not repository and not repository_version:\n            raise serializers.ValidationError(\n                _(\"Either the 'repository' or 'repository_version' need to be specified\"))\n        elif not repository and repository_version:\n            return data\n        elif repository and not repository_version:\n            version = models.RepositoryVersion.latest(repository)\n            if version:\n                new_data = {'repository_version': version}\n                new_data.update(data)\n                return new_data\n            else:\n                raise serializers.ValidationError(\n                    detail=_('Repository has no version available to create Publication from'))\n        raise serializers.ValidationError(\n            _(\"Either the 'repository' or 'repository_version' need to be specified \"\n              \"but not both.\")\n        )\n\n    class Meta:\n        abstract = True\n        model = models.Publication\n        fields = MasterModelSerializer.Meta.fields + (\n            'publisher',\n            'repository_version',\n            'repository'\n        )\n\n\nclass ContentGuardSerializer(MasterModelSerializer):\n    _href = DetailIdentityField()\n\n    name = serializers.CharField(\n        help_text=_('The unique name.')\n    )\n    description = serializers.CharField(\n        help_text=_('An optional description.'),\n        allow_blank=True,\n        required=False\n    )\n\n    class Meta:\n        model = models.ContentGuard\n        fields = MasterModelSerializer.Meta.fields + (\n            'name',\n            'description'\n        )\n\n\nclass BaseDistributionSerializer(MasterModelSerializer):\n    _href = DetailIdentityField()\n    base_path = serializers.CharField(\n        help_text=_('The base (relative) path component of the published url. Avoid paths that \\\n                    overlap with other distribution base paths (e.g. \"foo\" and \"foo/bar\")'),\n        validators=[validators.MaxLengthValidator(\n            models.BaseDistribution._meta.get_field('base_path').max_length,\n            message=_('`base_path` length must be less than {} characters').format(\n                models.BaseDistribution._meta.get_field('base_path').max_length\n            )),\n            UniqueValidator(queryset=models.BaseDistribution.objects.all()),\n        ]\n    )\n    base_url = BaseURLField(\n        source='base_path', read_only=True,\n        help_text=_('The URL for accessing the publication as defined by this distribution.')\n    )\n    content_guard = DetailRelatedField(\n        required=False,\n        help_text=_('An optional content-guard.'),\n        queryset=models.ContentGuard.objects.all(),\n        allow_null=True\n    )\n    name = serializers.CharField(\n        help_text=_('A unique name. Ex, `rawhide` and `stable`.'),\n        validators=[validators.MaxLengthValidator(\n            models.BaseDistribution._meta.get_field('name').max_length,\n            message=_('`name` length must be less than {} characters').format(\n                models.BaseDistribution._meta.get_field('name').max_length\n            )),\n            UniqueValidator(queryset=models.BaseDistribution.objects.all())]\n    )\n    remote = DetailRelatedField(\n        required=False,\n        help_text=_('Remote that can be used to fetch content when using pull-through caching.'),\n        queryset=models.Remote.objects.all(),\n        allow_null=True\n    )\n\n    class Meta:\n        abstract = True\n        model = models.BaseDistribution\n        fields = ModelSerializer.Meta.fields + (\n            'base_path',\n            'base_url',\n            'content_guard',\n            'name',\n            'remote',\n        )\n\n    def _validate_path_overlap(self, path):\n        # look for any base paths nested in path\n        search = path.split(\"/\")[0]\n        q = Q(base_path=search)\n        for subdir in path.split(\"/\")[1:]:\n            search = \"/\".join((search, subdir))\n            q |= Q(base_path=search)\n\n        # look for any base paths that nest path\n        q |= Q(base_path__startswith='{}/'.format(path))\n        qs = models.BaseDistribution.objects.filter(q)\n\n        if self.instance is not None:\n            qs = qs.exclude(pk=self.instance.pk)\n\n        match = qs.first()\n        if match:\n            raise serializers.ValidationError(detail=_(\"Overlaps with existing distribution '\"\n                                                       \"{}'\").format(match.name))\n\n        return path\n\n    def validate_base_path(self, path):\n        self._validate_relative_path(path)\n        return self._validate_path_overlap(path)\n\n\nclass PublicationDistributionSerializer(BaseDistributionSerializer):\n    publication = DetailRelatedField(\n        required=False,\n        help_text=_('Publication to be served'),\n        queryset=models.Publication.objects.exclude(complete=False),\n        allow_null=True\n    )\n\n    class Meta:\n        abstract = True\n        fields = BaseDistributionSerializer.Meta.fields + (\n            'publication',\n        )\n\n\nclass RepositoryVersionDistributionSerializer(BaseDistributionSerializer):\n    repository = RelatedField(\n        required=False,\n        help_text=_('The latest RepositoryVersion for this Repository will be served.'),\n        queryset=models.Repository.objects.all(),\n        view_name='repositories-detail',\n        allow_null=True\n    )\n    repository_version = NestedRelatedField(\n        required=False,\n        help_text=_('RepositoryVersion to be served'),\n        queryset=models.RepositoryVersion.objects.exclude(complete=False),\n        view_name='versions-detail',\n        allow_null=True,\n        lookup_field='number',\n        parent_lookup_kwargs={'repository_pk': 'repository__pk'},\n    )\n\n    class Meta:\n        abstract = True\n        fields = BaseDistributionSerializer.Meta.fields + (\n            'repository',\n            'repository_version',\n        )\n\n    def validate(self, data):\n        super().validate(data)\n\n        if 'repository' in data and 'repository_version' in data:\n            msg = _(\"The attributes 'repository' and 'repository_version' must be used\"\n                    \"exclusively.\")\n            raise serializers.ValidationError(msg)\n\n        return data\n", "path": "pulpcore/app/serializers/publication.py"}], "after_files": [{"content": "from gettext import gettext as _\n\nfrom django.core import validators\nfrom django.db.models import Q\n\nfrom rest_framework import serializers\nfrom rest_framework.validators import UniqueValidator\n\nfrom pulpcore.app import models\nfrom pulpcore.app.serializers import (\n    BaseURLField,\n    DetailIdentityField,\n    DetailRelatedField,\n    NestedRelatedField,\n    RelatedField,\n    MasterModelSerializer,\n    ModelSerializer,\n    validate_unknown_fields,\n)\n\n\nclass PublicationSerializer(MasterModelSerializer):\n    _href = DetailIdentityField()\n    repository_version = NestedRelatedField(\n        view_name='versions-detail',\n        lookup_field='number',\n        parent_lookup_kwargs={'repository_pk': 'repository__pk'},\n        queryset=models.RepositoryVersion.objects.all(),\n        required=False,\n    )\n    repository = serializers.HyperlinkedRelatedField(\n        help_text=_('A URI of the repository to be published.'),\n        required=False,\n        label=_('Repository'),\n        queryset=models.Repository.objects.all(),\n        view_name='repositories-detail',\n    )\n\n    def validate(self, data):\n        if hasattr(self, 'initial_data'):\n            validate_unknown_fields(self.initial_data, self.fields)\n\n        repository = data.pop('repository', None)  # not an actual field on publication\n        repository_version = data.get('repository_version')\n        if not repository and not repository_version:\n            raise serializers.ValidationError(\n                _(\"Either the 'repository' or 'repository_version' need to be specified\"))\n        elif not repository and repository_version:\n            return data\n        elif repository and not repository_version:\n            version = models.RepositoryVersion.latest(repository)\n            if version:\n                new_data = {'repository_version': version}\n                new_data.update(data)\n                return new_data\n            else:\n                raise serializers.ValidationError(\n                    detail=_('Repository has no version available to create Publication from'))\n        raise serializers.ValidationError(\n            _(\"Either the 'repository' or 'repository_version' need to be specified \"\n              \"but not both.\")\n        )\n\n    class Meta:\n        abstract = True\n        model = models.Publication\n        fields = MasterModelSerializer.Meta.fields + (\n            'publisher',\n            'repository_version',\n            'repository'\n        )\n\n\nclass ContentGuardSerializer(MasterModelSerializer):\n    _href = DetailIdentityField()\n\n    name = serializers.CharField(\n        help_text=_('The unique name.')\n    )\n    description = serializers.CharField(\n        help_text=_('An optional description.'),\n        allow_blank=True,\n        required=False\n    )\n\n    class Meta:\n        model = models.ContentGuard\n        fields = MasterModelSerializer.Meta.fields + (\n            'name',\n            'description'\n        )\n\n\nclass BaseDistributionSerializer(MasterModelSerializer):\n    \"\"\"\n    The Serializer for the BaseDistribution model.\n\n    The serializer deliberately omits the \"remote\" field, which is used for\n    pull-through caching only. Plugins implementing pull-through caching will\n    have to add the field in their derived serializer class like this::\n\n      remote = DetailRelatedField(\n          required=False,\n          help_text=_('Remote that can be used to fetch content when using pull-through caching.'),\n          queryset=models.Remote.objects.all(),\n          allow_null=True\n      )\n\n    \"\"\"\n\n    _href = DetailIdentityField()\n    base_path = serializers.CharField(\n        help_text=_('The base (relative) path component of the published url. Avoid paths that \\\n                    overlap with other distribution base paths (e.g. \"foo\" and \"foo/bar\")'),\n        validators=[validators.MaxLengthValidator(\n            models.BaseDistribution._meta.get_field('base_path').max_length,\n            message=_('`base_path` length must be less than {} characters').format(\n                models.BaseDistribution._meta.get_field('base_path').max_length\n            )),\n            UniqueValidator(queryset=models.BaseDistribution.objects.all()),\n        ]\n    )\n    base_url = BaseURLField(\n        source='base_path', read_only=True,\n        help_text=_('The URL for accessing the publication as defined by this distribution.')\n    )\n    content_guard = DetailRelatedField(\n        required=False,\n        help_text=_('An optional content-guard.'),\n        queryset=models.ContentGuard.objects.all(),\n        allow_null=True\n    )\n    name = serializers.CharField(\n        help_text=_('A unique name. Ex, `rawhide` and `stable`.'),\n        validators=[validators.MaxLengthValidator(\n            models.BaseDistribution._meta.get_field('name').max_length,\n            message=_('`name` length must be less than {} characters').format(\n                models.BaseDistribution._meta.get_field('name').max_length\n            )),\n            UniqueValidator(queryset=models.BaseDistribution.objects.all())]\n    )\n\n    class Meta:\n        abstract = True\n        model = models.BaseDistribution\n        fields = ModelSerializer.Meta.fields + (\n            'base_path',\n            'base_url',\n            'content_guard',\n            'name',\n        )\n\n    def _validate_path_overlap(self, path):\n        # look for any base paths nested in path\n        search = path.split(\"/\")[0]\n        q = Q(base_path=search)\n        for subdir in path.split(\"/\")[1:]:\n            search = \"/\".join((search, subdir))\n            q |= Q(base_path=search)\n\n        # look for any base paths that nest path\n        q |= Q(base_path__startswith='{}/'.format(path))\n        qs = models.BaseDistribution.objects.filter(q)\n\n        if self.instance is not None:\n            qs = qs.exclude(pk=self.instance.pk)\n\n        match = qs.first()\n        if match:\n            raise serializers.ValidationError(detail=_(\"Overlaps with existing distribution '\"\n                                                       \"{}'\").format(match.name))\n\n        return path\n\n    def validate_base_path(self, path):\n        self._validate_relative_path(path)\n        return self._validate_path_overlap(path)\n\n\nclass PublicationDistributionSerializer(BaseDistributionSerializer):\n    publication = DetailRelatedField(\n        required=False,\n        help_text=_('Publication to be served'),\n        queryset=models.Publication.objects.exclude(complete=False),\n        allow_null=True\n    )\n\n    class Meta:\n        abstract = True\n        fields = BaseDistributionSerializer.Meta.fields + (\n            'publication',\n        )\n\n\nclass RepositoryVersionDistributionSerializer(BaseDistributionSerializer):\n    repository = RelatedField(\n        required=False,\n        help_text=_('The latest RepositoryVersion for this Repository will be served.'),\n        queryset=models.Repository.objects.all(),\n        view_name='repositories-detail',\n        allow_null=True\n    )\n    repository_version = NestedRelatedField(\n        required=False,\n        help_text=_('RepositoryVersion to be served'),\n        queryset=models.RepositoryVersion.objects.exclude(complete=False),\n        view_name='versions-detail',\n        allow_null=True,\n        lookup_field='number',\n        parent_lookup_kwargs={'repository_pk': 'repository__pk'},\n    )\n\n    class Meta:\n        abstract = True\n        fields = BaseDistributionSerializer.Meta.fields + (\n            'repository',\n            'repository_version',\n        )\n\n    def validate(self, data):\n        super().validate(data)\n\n        if 'repository' in data and 'repository_version' in data:\n            msg = _(\"The attributes 'repository' and 'repository_version' must be used\"\n                    \"exclusively.\")\n            raise serializers.ValidationError(msg)\n\n        return data\n", "path": "pulpcore/app/serializers/publication.py"}]}