Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 41 additions & 18 deletions ietf/api/serializers_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@
from rest_framework import serializers

from ietf.doc.expire import move_draft_files_to_archive
from ietf.doc.models import DocumentAuthor, Document, RfcAuthor, RelatedDocument, State, \
DocEvent
from ietf.doc.models import (
DocumentAuthor,
Document,
RelatedDocument,
State,
DocEvent,
RfcAuthor,
)
from ietf.doc.serializers import RfcAuthorSerializer
from ietf.doc.utils import default_consensus, prettify_std_name, update_action_holders
from ietf.group.models import Group
from ietf.name.models import StreamName, StdLevelName, FormalLanguageName
Expand Down Expand Up @@ -201,23 +208,39 @@ class Meta:
read_only_fields = ["id", "name"]


class AuthorSerializer(serializers.ModelSerializer):
"""Serialize an RfcAuthor record
class EditableRfcSerializer(serializers.ModelSerializer):
# Would be nice to reconcile this with ietf.doc.serializers.RfcSerializer.
# The purposes of that serializer (representing data for Red) and this one
# (accepting updates from Purple) are different enough that separate formats
# may be needed, but if not it'd be nice to have a single RfcSerializer that
# can serve both.
#
# For now, only handles authors
authors = RfcAuthorSerializer(many=True, min_length=1, source="rfcauthor_set")

todo fix naming confusion with ietf.doc.serializers.RfcAuthorSerializer
"""
class Meta:
model = RfcAuthor
fields = [
"id",
"titlepage_name",
"is_editor",
"person",
"email",
"affiliation",
"country",
]

model = Document
fields = ["id", "authors"]

def update(self, instance, validated_data):
authors_data = validated_data.pop("rfcauthor_set", None)
if authors_data is not None:
# Construct unsaved instances from validated author data
new_authors = []
for count, author_data in enumerate(authors_data):
new_authors.append(
RfcAuthor(
document=instance,
order=count + 1,
**author_data,
)
)
# Commit author changes
with transaction.atomic():
instance.rfcauthor_set.all().delete()
for author in new_authors:
author.save()
return instance

class RfcPubSerializer(serializers.ModelSerializer):
# publication-related fields
Expand Down Expand Up @@ -273,7 +296,7 @@ class RfcPubSerializer(serializers.ModelSerializer):
regex=r"^(bcp|std|fyi)[1-9][0-9]{0,4}$",
)
)
authors = AuthorSerializer(many=True)
authors = RfcAuthorSerializer(many=True)

class Meta:
model = Document
Expand Down
9 changes: 6 additions & 3 deletions ietf/api/views_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from rest_framework.pagination import LimitOffsetPagination

from ietf.api.serializers_rpc import (
AuthorSerializer,
PersonSerializer,
FullDraftSerializer,
DraftSerializer,
Expand All @@ -33,8 +32,10 @@
RfcWithAuthorsSerializer,
DraftWithAuthorsSerializer,
NotificationAckSerializer, RfcPubSerializer, RfcFileSerializer,
EditableRfcSerializer,
)
from ietf.doc.models import Document, DocHistory, RfcAuthor
from ietf.doc.serializers import RfcAuthorSerializer
from ietf.person.models import Email, Person


Expand Down Expand Up @@ -269,9 +270,11 @@ def bulk_authors(self, request):
responses=OriginalStreamSerializer(many=True),
)
)
class RfcViewSet(viewsets.GenericViewSet):
class RfcViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
queryset = Document.objects.filter(type_id="rfc")
api_key_endpoint = "ietf.api.views_rpc"
lookup_field = "rfc_number"
serializer_class = EditableRfcSerializer

@action(detail=False, serializer_class=OriginalStreamSerializer)
def rfc_original_stream(self, request):
Expand Down Expand Up @@ -328,7 +331,7 @@ class RfcAuthorViewSet(viewsets.ModelViewSet):
api_key_endpoint = "ietf.api.views_rpc"

queryset = RfcAuthor.objects.all()
serializer_class = AuthorSerializer
serializer_class = RfcAuthorSerializer
lookup_url_kwarg = "author_id"
rfc_number_param = "rfc_number"

Expand Down
23 changes: 21 additions & 2 deletions ietf/doc/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

class RfcAuthorSerializer(serializers.ModelSerializer):
"""Serializer for a DocumentAuthor in a response"""
email = serializers.EmailField(source="email.address", required=False)
datatracker_person_path = serializers.URLField(
source="person.get_absolute_url",
required=False,
Expand All @@ -28,7 +27,7 @@ class Meta:
"titlepage_name",
"is_editor",
"person",
"email",
"email", # relies on email.pk being email.address
"affiliation",
"country",
"datatracker_person_path",
Expand All @@ -54,6 +53,26 @@ def to_representation(self, instance):
)
return super().to_representation(instance)

def validate(self, data):
email = data.get("email")
if email is not None:
person = data.get("person")
if person is None:
raise serializers.ValidationError(
{
"email": "cannot have an email without a person",
},
code="email-without-person",
)
if email.person_id != person.pk:
raise serializers.ValidationError(
{
"email": "email must belong to person",
},
code="email-person-mismatch",
)
return data


@dataclass
class DocIdentifier:
Expand Down