o
    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                       sp  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searchsearch_operator_formatidtype
detail_url)r.   r/   r0   c                    s   t  j|i | t | _d S N)super__init__r   
seen_types)selfargskwargs	__class__ T/var/www/html/ndineBlogger/venv/lib/python3.10/site-packages/wagtail/api/v2/views.pyr3   B   s   zBaseAPIViewSet.__init__c                 C   s   | j j dS )Nr.   )modelobjectsallorder_byr5   r:   r:   r;   get_querysetK   s   zBaseAPIViewSet.get_querysetc                 C   s@   |   }| | | |}| |}| j|dd}| |jS )NT)many)rA   check_query_parametersfilter_querysetpaginate_querysetget_serializerget_paginated_responsedata)r5   requestqueryset
serializerr:   r:   r;   listing_viewN   s   


zBaseAPIViewSet.listing_viewc                 C   s   |   }| |}t|jS r1   )
get_objectrF   r   rH   )r5   rI   pkinstancerK   r:   r:   r;   detail_viewV   s   

zBaseAPIViewSet.detail_viewc                 C   s|   |   }z| ||}|d u r| jjW n | jjy!   tdw t| jj|| j|j}|d u r:t	d
| jjt|S )Nz	not foundzHCannot generate URL to detail view. Is '{}' installed in the API router?)rA   find_objectr<   DoesNotExistr   r"   rI   wagtailapi_routerrN   	Exceptionr-   r9   __name__r   )r5   rI   rJ   objurlr:   r:   r;   	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)r5   rJ   rI   r:   r:   r;   rQ   v   s   
zBaseAPIViewSet.find_objectc                    sT   t |trdt|i}t|tjdS t |tr$dt|i}t|tjdS t 	|S )Nmessager
   )

isinstancer   strr   r   HTTP_404_NOT_FOUNDr!   HTTP_400_BAD_REQUESTr2   handle_exception)r5   excrH   r8   r:   r;   ra   }   s   

zBaseAPIViewSet.handle_exceptionc                 C   s   dd |D S )Nc                 S   s"   g | ]}t |tr|nt|qS r:   )r]   r   .0fieldr:   r:   r;   
<listcomp>   s    z6BaseAPIViewSet._convert_api_fields.<locals>.<listcomp>r:   )clsr(   r:   r:   r;   _convert_api_fields   s   z"BaseAPIViewSet._convert_api_fieldsc                 C      |  | jtt|dd S )N
api_fieldsr:   )rh   body_fieldslistgetattrrg   r<   r:   r:   r;   get_body_fields      zBaseAPIViewSet.get_body_fieldsc                 C      dd |  |D S )Nc                 S      g | ]}|j qS r:   namerc   r:   r:   r;   rf          z8BaseAPIViewSet.get_body_fields_names.<locals>.<listcomp>)ro   rn   r:   r:   r;   get_body_fields_names      z$BaseAPIViewSet.get_body_fields_namesc                 C   ri   )Napi_meta_fieldsr:   )rh   meta_fieldsrl   rm   rn   r:   r:   r;   get_meta_fields   rp   zBaseAPIViewSet.get_meta_fieldsc                 C   rq   )Nc                 S   rr   r:   rs   rc   r:   r:   r;   rf      ru   z8BaseAPIViewSet.get_meta_fields_names.<locals>.<listcomp>)rz   rn   r:   r:   r;   get_meta_fields_names   rw   z$BaseAPIViewSet.get_meta_fields_namesc                 C   s   dd |  || | D S )Nc                 S   s    i | ]}|j d ur|j|j qS r1   )rK   rt   rc   r:   r:   r;   
<dictcomp>   s
    
zABaseAPIViewSet.get_field_serializer_overrides.<locals>.<dictcomp>)ro   rz   rn   r:   r:   r;   get_field_serializer_overrides   s   z-BaseAPIViewSet.get_field_serializer_overridesFc                    sf   |  || | }|r1t  |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                       g | ]}| v r|qS r:   r:   rc   database_fieldsr:   r;   rf          z7BaseAPIViewSet.get_available_fields.<locals>.<listcomp>)	rv   r{   set_meta
get_fieldsaddrt   hasattrr~   )rg   r<   db_fields_onlyr(   re   r:   r   r;   get_available_fields   s   

z#BaseAPIViewSet.get_available_fieldsc                 C   s
   |  |S r1   )r   rn   r:   r:   r;   get_detail_default_fields   s   
z(BaseAPIViewSet.get_detail_default_fieldsc                 C      | j d d  S r1   )listing_default_fieldsrn   r:   r:   r;   get_listing_default_fields      z)BaseAPIViewSet.get_listing_default_fieldsc                 C   r   r1   )nested_default_fieldsrn   r:   r:   r;   get_nested_default_fields   r   z(BaseAPIViewSet.get_nested_default_fieldsc                 C   sR   t | jj }t | j|jdd| j}|| }|r'tdd	t
| dS )zR
        Ensure that only valid query parameters are included in the URL.
        T)r   z=query parameter is not an operation or a recognised field: %s, N)r   rI   rZ   keysr   r<   unionknown_query_parametersr!   joinsorted)r5   rJ   query_parametersallowed_query_parametersunknown_parametersr:   r:   r;   rC      s   z%BaseAPIViewSet.check_query_parametersc              	      s  |  |}| |}|| }tt|}|s-| jD ]}	z||	 W q ty,   Y qw |r7t| 	| n|rAt| 
| nt| | |r]|d d dkr]t| |dd  }n|rp|d d dkrpt  |dd  }t }
i }|D ](\}}}|rz | W n ty   Y nw  | |r|||< |
| qw|
t| }|rtddt| i } D ]h}z|j|}W n ty   d }Y nw |r|jr||g }tt|dd tr|r|d d dvrt|}|dd	 |j}||}|r|d nt}|j|||d
d||< q||v rtd| q fdd|D   fdd| | D }t | |||| j!dS )Nr   *r   r,   zunknown fields: %sr   re   )r   r,   )r   FNT)nestedz#'%s' does not support nested fieldsc                    r   r:   r:   rc   r(   r:   r;   rf   B  r   z8BaseAPIViewSet._get_serializer_class.<locals>.<listcomp>c                    s&   i | ]}|d   v r|d  |d qS )r   r   r:   rc   r   r:   r;   r|   D  s
    z8BaseAPIViewSet._get_serializer_class.<locals>.<dictcomp>)ry   field_serializer_overrideschild_serializer_classesbase)"rv   r{   rl   r   fromkeysdetail_only_fieldsremove
ValueErrorr   r   r   r   KeyErrorr   r!   r   r   r   	get_fieldr   is_relationr[   r]   rm   r	   insertrelated_modelget_model_endpointr%   _get_serializer_classr}   itemsr    base_serializer_class)rg   routerr<   fields_configshow_detailsr   rk   ry   
all_fieldsre   mentioned_fields
sub_fields
field_namenegatedfield_sub_fieldsunknown_fieldsr   django_fieldchild_sub_fieldschild_modelchild_endpoint_classr   r:   r   r;   r      s   






z$BaseAPIViewSet._get_serializer_classc              
   C   s   | j }| jdkr|  j}nt|  }d|jv r7z	t|jd }W n ty6 } zt	dt
| d }~ww g }| jdkrAd}nd}| j| j j|||dS )NrL   r(   zfields error: %sFT)r   )rI   actionrA   r<   r/   rM   rZ   r$   r   r!   r^   r   rS   )r5   rI   r<   r   er   r:   r:   r;   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.
        )rI   viewr   )rI   rS   r@   r:   r:   r;   get_serializer_contextr  s   z%BaseAPIViewSet.get_serializer_contextc                    s   t   }d|d< |S )N   indent)r2   get_renderer_contextr5   contextr8   r:   r;   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
         r[   rL   listingrs   z	<int:pk>/rP   detailzfind/rX   find)r   as_view)rg   r:   r:   r;   get_urlpatterns  s   zBaseAPIViewSet.get_urlpatternsr   c                 C   s    |r
|d }t |S d}t |S )Nz:listingr   r   )rg   r<   	namespaceurl_namer:   r:   r;   get_model_listing_urlpath  s
   z(BaseAPIViewSet.get_model_listing_urlpathc                 C   s    |r|d }nd}t ||fdS )Nz:detailr   )r6   r   )rg   r<   rN   r   r   r:   r:   r;   get_object_detail_urlpath  s   
z(BaseAPIViewSet.get_object_detail_urlpath)F)FF)r   )/rU   
__module____qualname__r   r   renderer_classesr   pagination_classr   r   filter_backendsr<   	frozensetr   rk   ry   r   r   r   rt   r3   rA   rL   rP   rX   rQ   ra   classmethodrh   ro   rv   rz   r{   r}   r   r   r   r   rC   r   r    r   r   r   r   r   __classcell__r:   r:   r8   r;   r%   %   sn    		








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/   child_ofancestor_ofdescendant_oftranslation_oflocalesitetitle)	html_urlslugshow_in_menus	seo_titlesearch_descriptionfirst_published_atalias_ofparentr   )r   r   r   r   r   pagesc                    s&   t  |}ttdds|d |S NWAGTAIL_I18N_ENABLEDFr   )r2   r   rm   r   r   )rg   r<   detail_default_fieldsr8   r:   r;   r        
z)PagesAPIViewSet.get_detail_default_fieldsc                    s&   t  |}ttddr|d |S r   )r2   r   rm   r   append)rg   r<   r   r8   r:   r;   r     r   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_requestrI   	root_pager@   r:   r:   r;   get_root_page  s   zPagesAPIViewSet.get_root_pagec                    s$   j }tj  } fddtj dD }|D ]	}|j|dd}qd|jv rad|jd v rB|jd 	dd\}}||d	}nd
|jd i}zt
jjdi |}W n t
jy`   tdw t
 j }|r|}	|	j|jdd}ttddr|j D ]}
||	j|
ddO }q~|S | }|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 r:   )accept_requestrI   page)rd   restrictionr@   r:   r;   rf     s    
z5PagesAPIViewSet.get_base_queryset.<locals>.<listcomp>r   T)	inclusiver   :r   )hostnameportr   zQYour query returned multiple sites. Try adding a port number to your site filter.r   FNr:   )rI   r   r=   r>   liver   select_relatednot_descendant_ofrZ   splitr   r[   MultipleObjectsReturnedr!   r   r   r   rm   r   get_translationsnone)r5   rI   rJ   restricted_pagesrestricted_pager   r   queryr   base_querysettranslationr:   r@   r;   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y!   tdw |s<| jtkr-| 	 S | jj
j| 	 jddddS t|dkrR|d j
j| 	 jddddS | 	 j| S )	Nr/   ztype doesn't existrN   T)flat)pk__inr   r   )rI   rZ   r[   r#   LookupErrorr   r!   r<   r   r  r=   filtervalues_listlenr/   )r5   rI   models_typemodelsr:   r:   r;   rA   )  s$   

zPagesAPIViewSet.get_querysetc                    s   t   }|jS r1   )r2   rM   specific)r5   r   r8   r:   r;   rM   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y4   Y d S w |j|j	d
 r@|S t ||S )N	html_pathc                 S   s   g | ]}|r|qS r:   r:   )rd   	componentr:   r:   r;   rf   M  s    z/PagesAPIViewSet.find_object.<locals>.<listcomp>/rY   )r   r   rZ   r   r   r  router   r  r.   existsr2   rQ   )r5   rJ   rI   r   r   path_componentsr   r,   r8   r:   r;   rQ   I  s   

zPagesAPIViewSet.find_objectc                    s   t   }|  |d< |S )r   r  )r2   r   r  r   r8   r:   r;   r   Y  s   
z&PagesAPIViewSet.get_serializer_context)#rU   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r   r   rk   ry   r   r   r   rt   r   r<   r   r   r   r   r  rA   rM   rQ   r   r   r:   r:   r8   r;   r     sF    
		>r   N)4collectionsr   django.confr   django.core.exceptionsr   django.httpr   django.shortcutsr   django.urlsr   r   modelcluster.fieldsr	   rest_frameworkr   rest_framework.renderersr   r   rest_framework.responser   rest_framework.viewsetsr   wagtail.apir   wagtail.modelsr   r   r   filtersr   r   r   r   r   r   r   r   
paginationr   serializersr   r   r    utilsr!   r"   r#   r$   r%   r   r:   r:   r:   r;   <module>   s*    (
  |