o
    h/                     @   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                   @       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 N selfinstancer   r   Z/var/www/html/ndineBlogger/venv/lib/python3.10/site-packages/wagtail/api/v2/serializers.pyget_attribute      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          r   c                   @   r   )DetailUrlFieldz
    Serializes the "detail_url" field of each object.

    Example:
    "detail_url": "http://api.example.com/v1/images/1/"
    c                 C   s,   t | jd | jd t||j}|r|S t)Nrouterrequest)r   r   r   pkr   )r   r   urlr   r   r   r   '   s   zDetailUrlField.get_attributec                 C   r   r   r   )r   r-   r   r   r   r#   2   r   z DetailUrlField.to_representationNr$   r   r   r   r   r)      s    r)   c                   @   r   )PageHtmlUrlFieldz{
    Serializes the "html_url" field for pages.

    Example:
    "html_url": "http://www.example.com/blog/blog-post/"
    c                 C   r   r   r   r   r   r   r   r   >   r   zPageHtmlUrlField.get_attributec                 C   s   z|j W S  ty   Y d S w r   )full_urlr   r   pager   r   r   r#   A   s
   z"PageHtmlUrlField.to_representationNr$   r   r   r   r   r.   6   r(   r.   c                   @   r   )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   r   r   r   r   r   r   r   r   T   r   zPageTypeField.get_attributec                 C   s:   |j d u rd S |j jjd |j j }|j | jd j|< |S r   )specific_classr   r   r   r   r    )r   r1   r"   r   r   r   r#   W   s
   
zPageTypeField.to_representationNr$   r   r   r   r   r2   H   s    r2   c                   @   r   )PageLocaleFieldz2
    Serializes the "locale" field for pages.
    c                 C   r   r   r   r   r   r   r   r   d   r   zPageLocaleField.get_attributec                 C   s   |j jS r   )localelanguage_coder0   r   r   r   r#   g   s   z!PageLocaleField.to_representationNr$   r   r   r   r   r4   _       r4   c                       (   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                    "   | d| _t j|i | d S Nserializer_classpopr<   super__init__r   argskwargs	__class__r   r   r@   z      zRelatedField.__init__c                 C   s   | j | jd}||S )Nr   )r<   r   r#   )r   value
serializerr   r   r   r#   ~   s   
zRelatedField.to_representationr   r%   r&   r'   r@   r#   __classcell__r   r   rD   r   r9   k   s    r9   c                   @   r   )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 )Nbase_queryset)id)
get_parentr   filterrN   exists)r   r   parentr   r   r   r      s   zPageParentField.get_attributec                 C   0   t |jg dg dtd}|| jd}||S N)rN   r   
detail_urlhtml_urltitle)r   rU   rV   )meta_fieldsbaserG   get_serializer_classrE   PageSerializerr   r#   r   rH   r<   rI   r   r   r   r#         
z!PageParentField.to_representationNr$   r   r   r   r   rL      s    	rL   c                   @   r   )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   rS   rT   rZ   r]   r   r   r   r#      r^   z"PageAliasOfField.to_representationNr$   r   r   r   r   r_      r7   r_   c                       r8   )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                    r:   r;   r=   rA   rD   r   r   r@      rF   zChildRelationField.__init__c                    s$   | j | jd  fdd| D S )NrG   c                    s   g | ]}  |qS r   )r#   ).0child_objectrI   r   r   
<listcomp>   s    
z8ChildRelationField.to_representation.<locals>.<listcomp>)r<   r   allr   rH   r   rd   r   r#      s   
z$ChildRelationField.to_representationrJ   r   r   rD   r   ra      s    &ra   c                   @      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   )stream_blockget_api_representationr   rg   r   r   r   r#     s   zStreamField.to_representationNr   r%   r&   r'   r#   r   r   r   r   ri      s    #ri   c                   @   rh   )	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)flat)listrf   order_byvalues_listrg   r   r   r   r#     s   zTagsField.to_representationNrl   r   r   r   r   rm     s    rm   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	read_onlyc              	      s  t  }dd  j D } fdd|D } fdd|D }ddd |D v r,d |d< t  }|D ]%}z||}W n	 tyC   Y q1w |d u rNd ||j< q1||||j< q1|r]||d< |D ]-}z|jdkrj|j}||}W n	 tyy   Y q_w |d u rd ||j< q_||||j< q_|S )	Nc                 S   s   g | ]}|j s|qS r   )
write_onlyrb   fieldr   r   r   re   /  s    z4BaseSerializer.to_representation.<locals>.<listcomp>c                    s   g | ]
}|j  jv r|qS r   
field_namerX   rv   r   r   r   re   2  s    c                    s   g | ]
}|j  jvr|qS r   rx   rv   rz   r   r   re   5  s    rN   c                 S   s   g | ]}|j qS r   )ry   rv   r   r   r   re   8  s    metaadmin_display_title)r   r
   valuesr   r   ry   r#   specific_deferred)r   r   datar
   rX   r{   rw   	attributer   rz   r   r#   -  s@   

z BaseSerializer.to_representationc                    s*   t ||}t|trti fS t ||S r   )getattr
isinstancer	   rm   r?   build_property_field)r   ry   model_classrw   rD   r   r   r   `  s   

z#BaseSerializer.build_property_fieldc                    s(   t  ||\}}| j| |d< ||fS r;   )r?   build_relational_fieldchild_serializer_classes)r   ry   relation_infofield_classfield_kwargsrD   r   r   r   h  s
   z%BaseSerializer.build_relational_field)r   r%   r&   r   ModelSerializerserializer_field_mappingcopyupdatewagtailcore_fieldsri   r9   serializer_related_fieldr   r   r)   rU   r#   r   r   rK   r   r   rD   r   rr     s    


3rr   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 )r\   Trs   c                    sV   |j r$t| jd}dd t|D }||v r$|| jv r$td| j| ifS t ||S )Nmodelc                 S   s   i | ]	}|j jj|jqS r   )rw   remote_fieldrelated_namerelated_model)rb   child_relationr   r   r   
<dictcomp>|  s    z9PageSerializer.build_relational_field.<locals>.<dictcomp>r<   )to_manyr   Metar   r   ra   r?   r   )r   ry   r   r   child_relationsrD   r   r   r   w  s   

z%PageSerializer.build_relational_field)r   r%   r&   r2   r   r4   r5   r.   rV   rL   rR   r_   r`   r   rK   r   r   rD   r   r\   p  s    




r\   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&   r   ro   r
   r   field_namesmodel_r   r   r     s    r   )r   rX   r   
Serializer)ro   r   r   strr   )r   r   rX   field_serializer_overridesr   rY   r   attrsr   r   r   r[     s   
r[   )"collectionsr   django.urls.exceptionsr   modelcluster.modelsr   rest_frameworkr   r   rest_framework.fieldsr   r   taggit.managersr	   wagtailr
   r   utilsr   r   r)   r.   r2   r4   r9   rL   r_   ra   ri   rm   r   rr   r\   r[   r   r   r   r   <module>   s2    3(S 