a
    Dg
P                     @   s0  d dl mZ d dlmZ 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 d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ d dlmZmZmZ ddlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1 G dd deZ2G dd de2Z3dS )    )OrderedDict)settings)FieldDoesNotExist)Http404)redirect)pathreverse)ParentalKeystatus)BrowsableAPIRendererJSONRenderer)Response)GenericViewSet)APIField)PagePageViewRestrictionSite   )AncestorOfFilterChildOfFilterDescendantOfFilterFieldsFilterLocaleFilterOrderingFilterSearchFilterTranslationOfFilter)WagtailPagination)BaseSerializerPageSerializerget_serializer_class)BadRequestErrorget_object_detail_urlpage_models_from_stringparse_fields_parameterc                       sn  e Zd ZeegZeZeZ	g Z
dZeg dZdgZddgZg dZg dZg ZdZ fddZd	d
 Zdd Zdd Zdd Zdd Z fddZedd Zedd Zedd Zedd Zedd Z edd  Z!ed;d"d#Z"ed$d% Z#ed&d' Z$ed(d) Z%d*d+ Z&ed<d,d-Z'd.d/ Z(d0d1 Z) fd2d3Z*ed4d5 Z+ed=d7d8Z,ed>d9d:Z-  Z.S )?BaseAPIViewSetN)limitoffsetfieldsordersearchZsearch_operator_formatidtype
detail_url)r-   r.   r/   c                    s   t  j|i | t | _d S N)super__init__r   Z
seen_types)selfargskwargs	__class__ S/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/wagtail/api/v2/views.pyr2   B   s    zBaseAPIViewSet.__init__c                 C   s   | j j dS )Nr-   )modelobjectsallZorder_byr3   r8   r8   r9   get_querysetK   s    zBaseAPIViewSet.get_querysetc                 C   s@   |   }| | | |}| |}| j|dd}| |jS )NT)many)r>   check_query_parametersZfilter_querysetZpaginate_querysetget_serializerZget_paginated_responsedata)r3   requestqueryset
serializerr8   r8   r9   listing_viewN   s    


zBaseAPIViewSet.listing_viewc                 C   s   |   }| |}t|jS r0   )
get_objectrA   r   rB   )r3   rC   pkinstancerE   r8   r8   r9   detail_viewV   s    
zBaseAPIViewSet.detail_viewc                 C   s   |   }z | ||}|d u r&| jjW n | jjyF   tdY n0 t| jj|| j|j}|d u rxt	d
| jjt|S )Nz	not foundzHCannot generate URL to detail view. Is '{}' installed in the API router?)r>   find_objectr:   ZDoesNotExistr   r"   rC   wagtailapi_routerrH   	Exceptionr,   r7   __name__r   )r3   rC   rD   objurlr8   r8   r9   	find_view[   s"    zBaseAPIViewSet.find_viewc                 C   s    d|j v r|j|j d dS dS )z?
        Override this to implement more find methods.
        r-   r-   N)GETget)r3   rD   rC   r8   r8   r9   rK   v   s    
zBaseAPIViewSet.find_objectc                    sT   t |tr$dt|i}t|tjdS t |trHdt|i}t|tjdS t 	|S )Nmessager
   )

isinstancer   strr   r   ZHTTP_404_NOT_FOUNDr!   ZHTTP_400_BAD_REQUESTr1   handle_exception)r3   excrB   r6   r8   r9   rX   }   s    

zBaseAPIViewSet.handle_exceptionc                 C   s   dd |D S )Nc                 S   s"   g | ]}t |tr|nt|qS r8   )rV   r   .0fieldr8   r8   r9   
<listcomp>   s   z6BaseAPIViewSet._convert_api_fields.<locals>.<listcomp>r8   )clsr(   r8   r8   r9   _convert_api_fields   s    z"BaseAPIViewSet._convert_api_fieldsc                 C   s   |  | jtt|dd S )NZ
api_fieldsr8   )r_   body_fieldslistgetattrr^   r:   r8   r8   r9   get_body_fields   s    zBaseAPIViewSet.get_body_fieldsc                 C   s   dd |  |D S )Nc                 S   s   g | ]
}|j qS r8   namerZ   r8   r8   r9   r]          z8BaseAPIViewSet.get_body_fields_names.<locals>.<listcomp>)rd   rc   r8   r8   r9   get_body_fields_names   s    z$BaseAPIViewSet.get_body_fields_namesc                 C   s   |  | jtt|dd S )NZapi_meta_fieldsr8   )r_   meta_fieldsra   rb   rc   r8   r8   r9   get_meta_fields   s    zBaseAPIViewSet.get_meta_fieldsc                 C   s   dd |  |D S )Nc                 S   s   g | ]
}|j qS r8   re   rZ   r8   r8   r9   r]      rg   z8BaseAPIViewSet.get_meta_fields_names.<locals>.<listcomp>)rj   rc   r8   r8   r9   get_meta_fields_names   s    z$BaseAPIViewSet.get_meta_fields_namesc                 C   s   dd |  || | D S )Nc                 S   s    i | ]}|j d ur|j|j qS r0   )rE   rf   rZ   r8   r8   r9   
<dictcomp>   s   
zABaseAPIViewSet.get_field_serializer_overrides.<locals>.<dictcomp>)rd   rj   rc   r8   r8   r9   get_field_serializer_overrides   s    z-BaseAPIViewSet.get_field_serializer_overridesFc                    sf   |  || | }|rbt  |j D ]&} |j t|dr( |j q( fdd|D }|S )a9  
        Returns a list of all the fields that can be used in the API for the
        specified model class.

        Setting db_fields_only to True will remove all fields that do not have
        an underlying column in the database (eg, type/detail_url and any custom
        fields that are callables)
        attnamec                    s   g | ]}| v r|qS r8   r8   rZ   Zdatabase_fieldsr8   r9   r]      rg   z7BaseAPIViewSet.get_available_fields.<locals>.<listcomp>)	rh   rk   set_metaZ
get_fieldsaddrf   hasattrrn   )r^   r:   db_fields_onlyr(   r\   r8   ro   r9   get_available_fields   s    

z#BaseAPIViewSet.get_available_fieldsc                 C   s
   |  |S r0   )ru   rc   r8   r8   r9   get_detail_default_fields   s    z(BaseAPIViewSet.get_detail_default_fieldsc                 C   s   | j d d  S r0   )listing_default_fieldsrc   r8   r8   r9   get_listing_default_fields   s    z)BaseAPIViewSet.get_listing_default_fieldsc                 C   s   | j d d  S r0   )nested_default_fieldsrc   r8   r8   r9   get_nested_default_fields   s    z(BaseAPIViewSet.get_nested_default_fieldsc                 C   sR   t | jj }t | j|jdd| j}|| }|rNtdd	t
| dS )zR
        Ensure that only valid query parameters are included in the URL.
        T)rt   z=query parameter is not an operation or a recognised field: %s, N)rp   rC   rS   keysru   r:   unionknown_query_parametersr!   joinsorted)r3   rD   Zquery_parametersZallowed_query_parametersZunknown_parametersr8   r8   r9   r@      s    z%BaseAPIViewSet.check_query_parametersc              	      s  |  |}| |}|| }tt|}|s\| jD ]&}	z||	 W q4 tyX   Y q40 q4|rpt| 	| n"|rt| 
| nt| | |r|d d dkrt| |dd  }n&|r|d d dkrt  |dd  }t }
i }|D ]X\}}}|r&z | W n ty"   Y n0 n | |r>|||< |
| q|
t| }|rrtddt| i } D ]}z|j|}W n ty   d }Y n0 |r<|jr<||g }tt|dd tr|r|d d dvrt|}|dd	 |j}||}|r |d nt}|j|||d
d||< n||v rztd| qz fdd|D   fdd| | D }t | |||| j!dS )Nr   *r   r+   zunknown fields: %sr{   r\   )r   r+   )r   FNT)nestedz#'%s' does not support nested fieldsc                    s   g | ]}| v r|qS r8   r8   rZ   r(   r8   r9   r]   B  rg   z8BaseAPIViewSet._get_serializer_class.<locals>.<listcomp>c                    s&   i | ]}|d   v r|d  |d qS )r   r   r8   rZ   r   r8   r9   rl   D  s   z8BaseAPIViewSet._get_serializer_class.<locals>.<dictcomp>)ri   field_serializer_overrideschild_serializer_classesbase)"rh   rk   ra   r   fromkeysdetail_only_fieldsremove
ValueErrorrp   rv   rz   rx   KeyErrorrr   r!   r   r   rq   	get_fieldr   Zis_relationrT   rV   rb   r	   insertZrelated_modelZget_model_endpointr%   _get_serializer_classrm   itemsr    base_serializer_class)r^   routerr:   fields_configshow_detailsr   r`   ri   Z
all_fieldsr\   Zmentioned_fieldsZ
sub_fields
field_nameZnegatedZfield_sub_fieldsZunknown_fieldsr   Zdjango_fieldZchild_sub_fieldsZchild_modelZchild_endpoint_classr   r8   r   r9   r      s    







z$BaseAPIViewSet._get_serializer_classc              
   C   s   | j }| jdkr|  j}nt|  }d|jv r|zt|jd }W q tyx } zt	dt
| W Y d }~qd }~0 0 ng }| jdkrd}nd}| j| j j|||dS )NrF   r(   zfields error: %sFT)r   )rC   actionr>   r:   r.   rG   rS   r$   r   r!   rW   r   rL   )r3   rC   r:   r   er   r8   r8   r9   r    R  s&    

(
z#BaseAPIViewSet.get_serializer_classc                 C   s   | j | | j jdS )U
        The serialization context differs between listing and detail views.
        )rC   viewr   )rC   rL   r=   r8   r8   r9   get_serializer_contextr  s    z%BaseAPIViewSet.get_serializer_contextc                    s   t   }d|d< |S )N   indent)r1   get_renderer_contextr3   contextr6   r8   r9   r   |  s    
z#BaseAPIViewSet.get_renderer_contextc                 C   sF   t d| ddiddt d| ddiddt d	| dd
iddgS )zF
        This returns a list of URL patterns for the endpoint
         rT   rF   listingre   z	<int:pk>/rJ   detailzfind/rQ   find)r   Zas_view)r^   r8   r8   r9   get_urlpatterns  s    zBaseAPIViewSet.get_urlpatternsr   c                 C   s   |r|d }nd}t |S )Nz:listingr   r   )r^   r:   	namespaceurl_namer8   r8   r9   get_model_listing_urlpath  s    
z(BaseAPIViewSet.get_model_listing_urlpathc                 C   s    |r|d }nd}t ||fdS )Nz:detailr   )r4   r   )r^   r:   rH   r   r   r8   r8   r9   get_object_detail_urlpath  s    
z(BaseAPIViewSet.get_object_detail_urlpath)F)FF)r   )r   )/rN   
__module____qualname__r   r   Zrenderer_classesr   Zpagination_classr   r   filter_backendsr:   	frozensetr~   r`   ri   rw   ry   r   rf   r2   r>   rF   rJ   rQ   rK   rX   classmethodr_   rd   rh   rj   rk   rm   ru   rv   rx   rz   r@   r   r    r   r   r   r   r   __classcell__r8   r8   r6   r9   r%   %   sl   		








 q 


r%   c                       s   e Zd ZeZeeeee	e
eegZejg dZejdg Zejg d Zejg d Zejdg ZdgZdZeZe fddZe fd	d
Zdd Zdd Zdd Z fddZ fddZ  fddZ!  Z"S )PagesAPIViewSet)r.   Zchild_ofZancestor_ofdescendant_ofZtranslation_oflocalesitetitle)	html_urlslugZshow_in_menusZ	seo_titleZsearch_descriptionfirst_published_atZalias_ofparentr   )r   r   r   r   r   Zpagesc                    s&   t  |}ttdds"|d |S NWAGTAIL_I18N_ENABLEDFr   )r1   rv   rb   r   r   )r^   r:   Zdetail_default_fieldsr6   r8   r9   rv     s    
z)PagesAPIViewSet.get_detail_default_fieldsc                    s&   t  |}ttddr"|d |S r   )r1   rx   rb   r   append)r^   r:   rw   r6   r8   r9   rx     s    
z*PagesAPIViewSet.get_listing_default_fieldsc                 C   s   t | jjS )zY
        Returns the page that is used when the `&child_of=root` filter is used.
        )r   find_for_requestrC   	root_pager=   r8   r8   r9   get_root_page  s    zPagesAPIViewSet.get_root_pagec                    s.   j }tj  } fddtj dD }|D ]}|j|dd}q6d|jv rd|jd v r|jd 	dd\}}||d	}nd
|jd i}zt
jjf i |}W q t
jy   tdY q0 nt
 j }|r"|}	|	j|jdd}ttddr*|j D ]}
||	j|
ddO }qn| }|S )z
        Returns a queryset containing all pages that can be seen by this user.

        This is used as the base for get_queryset and is also used to find the
        parent pages when using the child_of and descendant_of filters as well.
        c                    s   g | ]}|  js|jqS r8   )Zaccept_requestrC   page)r[   Zrestrictionr=   r8   r9   r]     s   z5PagesAPIViewSet.get_base_queryset.<locals>.<listcomp>r   T)Z	inclusiver   :r   )hostnameportr   zQYour query returned multiple sites. Try adding a port number to your site filter.r   F)rC   r   r;   r<   Zliver   Zselect_relatedZnot_descendant_ofrS   splitr   rT   ZMultipleObjectsReturnedr!   r   r   r   rb   r   Zget_translationsnone)r3   rC   rD   Zrestricted_pagesZrestricted_pager   r   queryr   base_querysettranslationr8   r=   r9   get_base_queryset  s<    


z!PagesAPIViewSet.get_base_querysetc              	   C   s   | j }z"|jdd }|r"t|p$g }W n ttfyF   tdY n0 |s~| jtkr^| 	 S | jj
j| 	 jddddS n:t|dkr|d j
j| 	 jddddS | 	 j| S d S )	Nr.   ztype doesn't existrH   T)Zflat)Zpk__inr   r   )rC   rS   rT   r#   LookupErrorr   r!   r:   r   r   r;   filterZvalues_listlenr.   )r3   rC   Zmodels_typemodelsr8   r8   r9   r>   )  s"    

zPagesAPIViewSet.get_querysetc                    s   t   }|jS r0   )r1   rG   specific)r3   r   r6   r8   r9   rG   E  s    
zPagesAPIViewSet.get_objectc                    s   t |}d|jv r|d ur|jd }dd |dD }z|jj||\}}}W n tyh   Y d S 0 |j|j	d
 r|S t ||S )NZ	html_pathc                 S   s   g | ]}|r|qS r8   r8   )r[   	componentr8   r8   r9   r]   M  rg   z/PagesAPIViewSet.find_object.<locals>.<listcomp>/rR   )r   r   rS   r   r   r   Zrouter   r   r-   existsr1   rK   )r3   rD   rC   r   r   Zpath_componentsr   r+   r6   r8   r9   rK   I  s    

zPagesAPIViewSet.find_objectc                    s   t   }|  |d< |S )r   r   )r1   r   r   r   r6   r8   r9   r   Y  s    
z&PagesAPIViewSet.get_serializer_context)#rN   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r~   r}   r`   ri   rw   ry   r   rf   r   r:   r   rv   rx   r   r   r>   rG   rK   r   r   r8   r8   r6   r9   r     sD   
		>r   N)4collectionsr   Zdjango.confr   Zdjango.core.exceptionsr   Zdjango.httpr   Zdjango.shortcutsr   Zdjango.urlsr   r   Zmodelcluster.fieldsr	   Zrest_frameworkr   Zrest_framework.renderersr   r   Zrest_framework.responser   Zrest_framework.viewsetsr   Zwagtail.apir   Zwagtail.modelsr   r   r   filtersr   r   r   r   r   r   r   r   Z
paginationr   Zserializersr   r   r    utilsr!   r"   r#   r$   r%   r   r8   r8   r8   r9   <module>   s(   (
  |