a
    Dg/                     @   sT  d dl mZ d dlmZ d dlmZ d dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZ dd	lmZ G d
d de
ZG dd de
ZG dd de
ZG dd de
ZG dd de
ZG dd dejZG dd dejZG dd dejZG dd de
ZG dd de
ZG dd de
ZG d d! d!ejZG d"d# d#eZ d$d$efd%d&Z!d$S )'    )OrderedDict)NoReverseMatch)get_all_child_relations)	relationsserializers)Field	SkipField)_TaggableManager)fields   )get_object_detail_urlc                   @   s    e Zd ZdZdd Zdd ZdS )	TypeFieldze
    Serializes the "type" field of each object.

    Example:
    "type": "wagtailimages.Image"
    c                 C   s   |S N selfinstancer   r   Y/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/wagtail/api/v2/serializers.pyget_attribute   s    zTypeField.get_attributec                 C   s2   t |jjd t |j }t || jd j|< |S N.view)type_meta	app_label__name__context
seen_types)r   objnamer   r   r   to_representation   s    zTypeField.to_representationNr   
__module____qualname____doc__r   r    r   r   r   r   r      s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )DetailUrlFieldz
    Serializes the "detail_url" field of each object.

    Example:
    "detail_url": "http://api.example.com/v1/images/1/"
    c                 C   s0   t | jd | jd t||j}|r(|S td S )NZrouterrequest)r   r   r   pkr   )r   r   urlr   r   r   r   '   s    zDetailUrlField.get_attributec                 C   s   |S r   r   )r   r(   r   r   r   r    2   s    z DetailUrlField.to_representationNr!   r   r   r   r   r%      s   r%   c                   @   s    e Zd ZdZdd Zdd ZdS )PageHtmlUrlFieldz{
    Serializes the "html_url" field for pages.

    Example:
    "html_url": "http://www.example.com/blog/blog-post/"
    c                 C   s   |S r   r   r   r   r   r   r   >   s    zPageHtmlUrlField.get_attributec                 C   s"   z|j W S  ty   Y d S 0 d S r   )full_urlr   r   pager   r   r   r    A   s    z"PageHtmlUrlField.to_representationNr!   r   r   r   r   r)   6   s   r)   c                   @   s    e Zd ZdZdd Zdd ZdS )PageTypeFielda  
    Serializes the "type" field for pages.

    This takes into account the fact that we sometimes may not have the "specific"
    page object by calling "page.specific_class" instead of looking at the object's
    type.

    Example:
    "type": "blog.BlogPage"
    c                 C   s   |S r   r   r   r   r   r   r   T   s    zPageTypeField.get_attributec                 C   s:   |j d u rd S |j jjd |j j }|j | jd j|< |S r   )Zspecific_classr   r   r   r   r   )r   r,   r   r   r   r   r    W   s
    
zPageTypeField.to_representationNr!   r   r   r   r   r-   H   s   r-   c                   @   s    e Zd ZdZdd Zdd ZdS )PageLocaleFieldz2
    Serializes the "locale" field for pages.
    c                 C   s   |S r   r   r   r   r   r   r   d   s    zPageLocaleField.get_attributec                 C   s   |j jS r   )localeZlanguage_coder+   r   r   r   r    g   s    z!PageLocaleField.to_representationNr!   r   r   r   r   r.   _   s   r.   c                       s(   e Zd ZdZ fddZdd Z  ZS )RelatedFieldz
    Serializes related objects (eg, foreign keys).

    Example:

    "feed_image": {
        "id": 1,
        "meta": {
            "type": "wagtailimages.Image",
            "detail_url": "http://api.example.com/v1/images/1/"
        }
    }
    c                    s"   | d| _t j|i | d S Nserializer_classpopr2   super__init__r   argskwargs	__class__r   r   r6   z   s    zRelatedField.__init__c                 C   s   | j | jd}||S )Nr   )r2   r   r    )r   value
serializerr   r   r   r    ~   s    zRelatedField.to_representationr   r"   r#   r$   r6   r    __classcell__r   r   r:   r   r0   k   s   r0   c                   @   s    e Zd ZdZdd Zdd ZdS )PageParentFielda  
    Serializes the "parent" field on Page objects.

    Pages don't have a "parent" field so some extra logic is needed to find the
    parent page. That logic is implemented in this class.

    The representation is the same as the RelatedField class.
    c                 C   s(   |  }| jd j|jd r$|S d S )NZbase_queryset)id)Z
get_parentr   filterrB   exists)r   r   parentr   r   r   r      s    zPageParentField.get_attributec                 C   s0   t |jg dg dtd}|| jd}||S N)rB   r   
detail_urlhtml_urltitle)r   rG   rH   )meta_fieldsbaser<   get_serializer_classr;   PageSerializerr   r    r   r=   r2   r>   r   r   r   r       s    z!PageParentField.to_representationNr!   r   r   r   r   rA      s   	rA   c                   @   s    e Zd ZdZdd Zdd ZdS )PageAliasOfFieldz:
    Serializes the "alias_of" field on Page objects.
    c                 C   s   |j S r   )alias_ofr   r   r   r   r      s    zPageAliasOfField.get_attributec                 C   s0   t |jg dg dtd}|| jd}||S rF   rL   rO   r   r   r   r       s    z"PageAliasOfField.to_representationNr!   r   r   r   r   rP      s   rP   c                       s(   e Zd ZdZ fddZdd Z  ZS )ChildRelationFielda  
    Serializes child relations.

    Child relations are any model that is related to a Page using a ParentalKey.
    They are used for repeated fields on a page such as carousel items or related
    links.

    Child objects are part of the pages content so we nest them. The relation is
    represented as a list of objects.

    Example:

    "carousel_items": [
        {
            "id": 1,
            "meta": {
                "type": "demo.MyCarouselItem"
            },
            "title": "First carousel item",
            "image": {
                "id": 1,
                "meta": {
                    "type": "wagtailimages.Image",
                    "detail_url": "http://api.example.com/v1/images/1/"
                }
            }
        },
        {
            "id": 2,
            "meta": {
                "type": "demo.MyCarouselItem"
            },
            "title": "Second carousel item (no image)",
            "image": null
        }
    ]
    c                    s"   | d| _t j|i | d S r1   r3   r7   r:   r   r   r6      s    zChildRelationField.__init__c                    s$   | j | jd  fdd| D S )Nr<   c                    s   g | ]}  |qS r   )r    ).0Zchild_objectr>   r   r   
<listcomp>   s   z8ChildRelationField.to_representation.<locals>.<listcomp>)r2   r   allr   r=   r   rT   r   r       s    
z$ChildRelationField.to_representationr?   r   r   r:   r   rR      s   &rR   c                   @   s   e Zd ZdZdd ZdS )StreamFielda  
    Serializes StreamField values.

    Stream fields are stored in JSON format in the database. We reuse that in
    the API.

    Example:

    "body": [
        {
            "type": "heading",
            "value": {
                "text": "Hello world!",
                "size": "h1"
            }
        },
        {
            "type": "paragraph",
            "value": "Some content"
        }
        {
            "type": "image",
            "value": 1
        }
    ]

    Where "heading" is a struct block containing "text" and "size" fields, and
    "paragraph" is a simple text block.

    Note that foreign keys are represented slightly differently in stream fields
    to other parts of the API. In stream fields, a foreign key is represented
    by an integer (the ID of the related object) but elsewhere in the API,
    foreign objects are nested objects with id and meta as attributes.
    c                 C   s   |j || jS r   )Zstream_blockZget_api_representationr   rW   r   r   r   r      s    zStreamField.to_representationNr   r"   r#   r$   r    r   r   r   r   rX      s   #rX   c                   @   s   e Zd ZdZdd ZdS )	TagsFielda  
    Serializes django-taggit TaggableManager fields.

    These fields are a common way to link tags to objects in Wagtail. The API
    serializes these as a list of strings taken from the name attribute of each
    tag.

    Example:

    "tags": ["bird", "wagtail"]
    c                 C   s   t | djdddS )Nr   T)Zflat)listrV   Zorder_byZvalues_listrW   r   r   r   r      s    zTagsField.to_representationNrY   r   r   r   r   rZ     s   rZ   c                       sd   e Zd Zejj Zeej	e	i e
ZeddZeddZdd Z fddZ fddZ  ZS )	BaseSerializerTZ	read_onlyc              	      s(  t  }dd  j D } fdd|D } fdd|D }ddd |D v rXd |d< t  }|D ]N}z||}W n ty   Y qbY n0 |d u rd ||j< qb||||j< qb|r||d< |D ]`}z|jdkr|j}||}W n ty   Y qY n0 |d u rd ||j< q||||j< q|S )	Nc                 S   s   g | ]}|j s|qS r   )Z
write_onlyrS   fieldr   r   r   rU   /      z4BaseSerializer.to_representation.<locals>.<listcomp>c                    s   g | ]}|j  jv r|qS r   
field_namerJ   r^   r   r   r   rU   2  s   c                    s   g | ]}|j  jvr|qS r   ra   r^   rc   r   r   rU   5  r`   rB   c                 S   s   g | ]
}|j qS r   )rb   r^   r   r   r   rU   8  r`   metaZadmin_display_title)r   r
   valuesr   r   rb   r    Zspecific_deferred)r   r   datar
   rJ   rd   r_   	attributer   rc   r   r    -  s<    




z BaseSerializer.to_representationc                    s*   t ||}t|trti fS t ||S r   )getattr
isinstancer	   rZ   r5   build_property_field)r   rb   Zmodel_classr_   r:   r   r   rj   `  s    

z#BaseSerializer.build_property_fieldc                    s(   t  ||\}}| j| |d< ||fS r1   )r5   build_relational_fieldchild_serializer_classes)r   rb   relation_infoZfield_classZfield_kwargsr:   r   r   rk   h  s
    z%BaseSerializer.build_relational_field)r   r"   r#   r   ModelSerializerZserializer_field_mappingcopyupdatewagtailcore_fieldsrX   r0   Zserializer_related_fieldr   r   r%   rG   r    rj   rk   r@   r   r   r:   r   r\     s   


3r\   c                       sN   e Zd ZeddZeddZeddZe	ddZ
eddZ fddZ  ZS )rN   Tr]   c                    sV   |j rHt| jd}dd t|D }||v rH|| jv rHtd| j| ifS t ||S )Nmodelc                 S   s   i | ]}|j jj|jqS r   )r_   Zremote_fieldZrelated_nameZrelated_model)rS   Zchild_relationr   r   r   
<dictcomp>|  s   z9PageSerializer.build_relational_field.<locals>.<dictcomp>r2   )Zto_manyrh   Metar   rl   rR   r5   rk   )r   rb   rm   rr   Zchild_relationsr:   r   r   rk   w  s    
z%PageSerializer.build_relational_field)r   r"   r#   r-   r   r.   r/   r)   rH   rA   rE   rP   rQ   rk   r@   r   r   r:   r   rN   p  s   




rN   Nc                    sR   | G  fddd}|t ||p&i d}|r:|| ttjd |f|S )Nc                       s   e Zd ZZe ZdS )z"get_serializer_class.<locals>.MetaN)r   r"   r#   rr   r[   r
   r   field_namesZmodel_r   r   rt     s   rt   )rt   rJ   rl   
Serializer)r[   rp   r   strr   )rr   rv   rJ   Zfield_serializer_overridesrl   rK   rt   attrsr   ru   r   rM     s    
rM   )"collectionsr   Zdjango.urls.exceptionsr   Zmodelcluster.modelsr   Zrest_frameworkr   r   Zrest_framework.fieldsr   r   Ztaggit.managersr	   Zwagtailr
   rq   utilsr   r   r%   r)   r-   r.   r0   rA   rP   rR   rX   rZ   rn   r\   rN   rM   r   r   r   r   <module>   s0   3(S 