U
    {h
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                	       s~  e Zd ZeegZeZeZ	g Z
dZedddddddd	gZd
gZddgZd
ddgZd
ddg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dAd(d)Z"ed*d+ Z#ed,d- Z$ed.d/ Z%d0d1 Z&edBd2d3Z'd4d5 Z(d6d7 Z) fd8d9Z*ed:d; Z+edCd=d>Z,edDd?d@Z-  Z.S )EBaseAPIViewSetNlimitoffsetfieldsordersearchZsearch_operator_formatidtypeZ
detail_urlc                    s   t  j|| t | _d S N)super__init__r   Z
seen_types)selfargskwargs	__class__ \/var/www/dating/data/www/fatepal.com/env/lib/python3.8/site-packages/wagtail/api/v2/views.pyr1   B   s    zBaseAPIViewSet.__init__c                 C   s   | j j dS )Nr-   )modelobjectsallZorder_byr2   r7   r7   r8   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)r2   requestqueryset
serializerr7   r7   r8   listing_viewN   s    


zBaseAPIViewSet.listing_viewc                 C   s   |   }| |}t|jS r/   )
get_objectr@   r   rA   )r2   rB   pkinstancerD   r7   r7   r8   detail_viewV   s    
zBaseAPIViewSet.detail_viewc                 C   s   |   }z | ||}|d kr&| jjW n  | jjk
rH   tdY nX t| jj|| j|j}|d krzt	d
| jjt|S )Nz	not foundzHCannot generate URL to detail view. Is '{}' installed in the API router?)r=   find_objectr9   ZDoesNotExistr   r"   rB   wagtailapi_routerrG   	Exceptionr,   r6   __name__r   )r2   rB   rC   objurlr7   r7   r8   	find_view[   s(       zBaseAPIViewSet.find_viewc                 C   s    d|j kr|j|j d dS dS )z?
        Override this to implement more find methods.
        r-   r-   N)GETget)r2   rC   rB   r7   r7   r8   rJ   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_REQUESTr0   handle_exception)r2   excrA   r5   r7   r8   rW   }   s    

zBaseAPIViewSet.handle_exceptionc                 C   s   dd |D S )Nc                 S   s"   g | ]}t |tr|nt|qS r7   )rU   r   .0fieldr7   r7   r8   
<listcomp>   s   z6BaseAPIViewSet._convert_api_fields.<locals>.<listcomp>r7   )clsr(   r7   r7   r8   _convert_api_fields   s    z"BaseAPIViewSet._convert_api_fieldsc                 C   s   |  | jtt|dd S )NZ
api_fieldsr7   )r^   body_fieldslistgetattrr]   r9   r7   r7   r8   get_body_fields   s    zBaseAPIViewSet.get_body_fieldsc                 C   s   dd |  |D S )Nc                 S   s   g | ]
}|j qS r7   namerY   r7   r7   r8   r\      s     z8BaseAPIViewSet.get_body_fields_names.<locals>.<listcomp>)rc   rb   r7   r7   r8   get_body_fields_names   s    z$BaseAPIViewSet.get_body_fields_namesc                 C   s   |  | jtt|dd S )NZapi_meta_fieldsr7   )r^   meta_fieldsr`   ra   rb   r7   r7   r8   get_meta_fields   s    zBaseAPIViewSet.get_meta_fieldsc                 C   s   dd |  |D S )Nc                 S   s   g | ]
}|j qS r7   rd   rY   r7   r7   r8   r\      s     z8BaseAPIViewSet.get_meta_fields_names.<locals>.<listcomp>)rh   rb   r7   r7   r8   get_meta_fields_names   s    z$BaseAPIViewSet.get_meta_fields_namesc                 C   s   dd |  || | D S )Nc                 S   s    i | ]}|j d k	r|j|j qS r/   )rD   re   rY   r7   r7   r8   
<dictcomp>   s   
 zABaseAPIViewSet.get_field_serializer_overrides.<locals>.<dictcomp>)rc   rh   rb   r7   r7   r8   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 | ]}| kr|qS r7   r7   rY   Zdatabase_fieldsr7   r8   r\      s      z7BaseAPIViewSet.get_available_fields.<locals>.<listcomp>)	rf   ri   set_metaZ
get_fieldsaddre   hasattrrl   )r]   r9   db_fields_onlyr(   r[   r7   rm   r8   get_available_fields   s    

z#BaseAPIViewSet.get_available_fieldsc                 C   s
   |  |S r/   )rs   rb   r7   r7   r8   get_detail_default_fields   s    z(BaseAPIViewSet.get_detail_default_fieldsc                 C   s   | j d d  S r/   )listing_default_fieldsrb   r7   r7   r8   get_listing_default_fields   s    z)BaseAPIViewSet.get_listing_default_fieldsc                 C   s   | j d d  S r/   )nested_default_fieldsrb   r7   r7   r8   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)rr   z=query parameter is not an operation or a recognised field: %s, N)rn   rB   rR   keysrs   r9   unionknown_query_parametersr!   joinsorted)r2   rC   Zquery_parametersZallowed_query_parametersZunknown_parametersr7   r7   r8   r?      s    z%BaseAPIViewSet.check_query_parametersc              	      s  |  |}| |}|| }tt|}|s^| jD ](}	z||	 W q4 tk
rZ   Y q4X q4|rrt| 	| n"|rt| 
| nt| | |r|d d dkrt| |dd  }n&|r|d d dkrt  |dd  }t }
i }|D ]Z\}}}|r*z | W n tk
r&   Y nX n | |rB|||< |
| q|
t| }|rvtddt| i } D ]}z|j|}W n tk
r   d }Y nX |rB|jrB||g }tt|dd tr|r|d d dkrt|}|dd	 |j}||}|r&|d nt}|j|||d
d||< n||kr~td| q~ fdd|D   fdd| | D }t | |||| j!dS )Nr   *r   r+   zunknown fields: %sry   r[   )r   r+   )r   FNT)nestedz#'%s' does not support nested fieldsc                    s   g | ]}| kr|qS r7   r7   rY   r(   r7   r8   r\   B  s      z8BaseAPIViewSet._get_serializer_class.<locals>.<listcomp>c                    s&   i | ]}|d   kr|d  |d qS )r   r   r7   rY   r   r7   r8   rj   D  s    z8BaseAPIViewSet._get_serializer_class.<locals>.<dictcomp>)rg   field_serializer_overrideschild_serializer_classesbase)"rf   ri   r`   r   fromkeysdetail_only_fieldsremove
ValueErrorrn   rt   rx   rv   KeyErrorrp   r!   r}   r~   ro   	get_fieldr   Zis_relationrS   rU   ra   r	   insertZrelated_modelZget_model_endpointr%   _get_serializer_classrk   itemsr    base_serializer_class)r]   routerr9   fields_configshow_detailsr   r_   rg   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   r7   r   r8   r      s    





   

z$BaseAPIViewSet._get_serializer_classc              
   C   s   | j }| jdkr|  j}nt|  }d|jkrzzt|jd }W q~ tk
rv } zt	dt
| W 5 d }~X Y q~X ng }| jdkrd}nd}| j| j j|||dS )NrE   r(   zfields error: %sFT)r   )rB   actionr=   r9   r.   rF   rR   r$   r   r!   rV   r   rK   )r2   rB   r9   r   er   r7   r7   r8   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.
        )rB   viewr   )rB   rK   r<   r7   r7   r8   get_serializer_contextr  s    z%BaseAPIViewSet.get_serializer_contextc                    s   t   }d|d< |S )N   indent)r0   get_renderer_contextr2   contextr5   r7   r8   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
         rS   rE   listingrd   z	<int:pk>/rI   detailzfind/rP   find)r   Zas_view)r]   r7   r7   r8   get_urlpatterns  s    zBaseAPIViewSet.get_urlpatternsr   c                 C   s   |r|d }nd}t |S )Nz:listingr   r   )r]   r9   	namespaceurl_namer7   r7   r8   get_model_listing_urlpath  s    
z(BaseAPIViewSet.get_model_listing_urlpathc                 C   s    |r|d }nd}t ||fdS )Nz:detailr   )r3   r   )r]   r9   rG   r   r   r7   r7   r8   get_object_detail_urlpath  s    
z(BaseAPIViewSet.get_object_detail_urlpath)F)FF)r   )r   )/rM   
__module____qualname__r   r   Zrenderer_classesr   Zpagination_classr   r   filter_backendsr9   	frozensetr|   r_   rg   ru   rw   r   re   r1   r=   rE   rI   rP   rJ   rW   classmethodr^   rc   rf   rh   ri   rk   rs   rt   rv   rx   r?   r   r    r   r   r   r   r   __classcell__r7   r7   r5   r8   r%   %   s~   

		








   q 


r%   c                
       s   e Zd ZeZeeeee	e
eegZejdddddddgZejdg Zejd	d
dddddddg	 Zejdd	d
dg 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 )"PagesAPIViewSetr.   Zchild_ofZancestor_ofdescendant_ofZtranslation_oflocalesitetitleZhtml_urlZslugZshow_in_menusZ	seo_titleZsearch_descriptionZfirst_published_atZalias_ofparentZpagesc                    s&   t  |}ttdds"|d |S NWAGTAIL_I18N_ENABLEDFr   )r0   rt   ra   r   r   )r]   r9   Zdetail_default_fieldsr5   r7   r8   rt     s    
z)PagesAPIViewSet.get_detail_default_fieldsc                    s&   t  |}ttddr"|d |S r   )r0   rv   ra   r   append)r]   r9   ru   r5   r7   r8   rv     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_requestrB   	root_pager<   r7   r7   r8   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krd|jd kr|jd 	dd\}}||d	}nd
|jd i}zt
jjf |}W q t
jk
r   tdY qX 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 r7   )Zaccept_requestrB   page)rZ   Zrestrictionr<   r7   r8   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)rB   r   r:   r;   liver   Zselect_relatedZnot_descendant_ofrR   splitr   rS   ZMultipleObjectsReturnedr!   r   r   r   ra   r   Zget_translationsnone)r2   rB   rC   Zrestricted_pagesZrestricted_pager   r   queryr   base_querysettranslationr7   r<   r8   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k
rH   tdY nX |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 existrG   T)Zflat)Zpk__inr   r   )rB   rR   rS   r#   LookupErrorr   r!   r9   r   r   r:   filterZvalues_listlenr.   )r2   rB   Zmodels_typemodelsr7   r7   r8   r=   )  s"    

zPagesAPIViewSet.get_querysetc                    s   t   }|jS r/   )r0   rF   specific)r2   r   r5   r7   r8   rF   E  s    
zPagesAPIViewSet.get_objectc                    s   t |}d|jkr|d k	r|jd }dd |dD }z|jj||\}}}W n tk
rj   Y d S X |j|j	d
 r|S t ||S )NZ	html_pathc                 S   s   g | ]}|r|qS r7   r7   )rZ   	componentr7   r7   r8   r\   M  s      z/PagesAPIViewSet.find_object.<locals>.<listcomp>/rQ   )r   r   rR   r   r   r   Zrouter   r   r-   existsr0   rJ   )r2   rC   rB   r   r   Zpath_componentsr   r+   r5   r7   r8   rJ   I  s    

zPagesAPIViewSet.find_objectc                    s   t   }|  |d< |S )r   r   )r0   r   r   r   r5   r7   r8   r   Y  s    
z&PagesAPIViewSet.get_serializer_context)#rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r|   r{   r_   rg   ru   rw   r   re   r   r9   r   rt   rv   r   r   r=   rF   rJ   r   r   r7   r7   r5   r8   r     sp   
		>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   r7   r7   r7   r8   <module>   s(   (
  |