
    h5                     r   d Z ddlmZ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 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Z G d d      Z G d d      Z G d de      Z  G d d      Z! G d de!      Z" G d de"ejF                        Z$ G d de"ejJ                        Z&d Z'e!Z(y)a  
The views provide high-level utilities to integrate translation support into other projects.

The following mixins are available:

* :class:`ViewUrlMixin` - provide a ``get_view_url`` for the :ref:`{% get_translated_url %} <get_translated_url>` template tag.
* :class:`TranslatableSlugMixin` - enrich the :class:`~django.views.generic.detail.DetailView` to support translatable slugs.
* :class:`LanguageChoiceMixin` - add ``?language=xx`` support to a view (e.g. for editing).
* :class:`TranslatableModelFormMixin` - add support for translatable forms, e.g. for creating/updating objects.

The following views are available:

* :class:`TranslatableCreateView` - The :class:`~django.views.generic.edit.CreateView` with :class:`TranslatableModelFormMixin` support.
* :class:`TranslatableUpdateView` - The :class:`~django.views.generic.edit.UpdateView` with :class:`TranslatableModelFormMixin` support.
    )ImproperlyConfiguredObjectDoesNotExist)modelform_factory)Http404HttpResponsePermanentRedirect)reverse)translation)generic)ModelFormMixin)TranslatableModelForm)TranslatableModelMixin)get_active_language_choices)switch_language)get_language_parameterget_language_tabs)ViewUrlMixinTranslatableSlugMixinLanguageChoiceMixinTranslatableModelFormMixinTranslatableCreateViewTranslatableUpdateViewc                       e Zd ZdZdZd Zy)r   a  
    Provide a ``view.get_view_url`` method in the template.

    This tells the template what the exact canonical URL should be of a view.
    The :ref:`{% get_translated_url %} <get_translated_url>` template tag uses this
    to find the proper translated URL of the current page.

    Typically, setting the :attr:`view_url_name` just works::

        class ArticleListView(ViewUrlMixin, ListView):
            view_url_name = 'article:list'

    The :func:`get_view_url` will use the :attr:`view_url_name` together
    with ``view.args`` and ``view.kwargs`` construct the URL.
    When some arguments are translated (e.g. a slug), the :func:`get_view_url`
    can be overwritten to generate the proper URL::

        from parler.views import ViewUrlMixin, TranslatableUpdateView
        from parler.utils.context import switch_language

        class ArticleEditView(ViewUrlMixin, TranslatableUpdateView):
            view_url_name = 'article:edit'

            def get_view_url(self):
                with switch_language(self.object, get_language()):
                    return reverse(self.view_url_name, kwargs={'slug': self.object.slug})
    Nc                     | j                   s"t        d| j                  j                         t	        | j                   | j
                  | j                        S )a  
        This method is used by the ``get_translated_url`` template tag.

        By default, it uses the :attr:`view_url_name` to generate an URL.
        When the URL ``args`` and ``kwargs`` are translatable,
        override this function instead to generate the proper URL.
        z%Missing `view_url_name` attribute on )argskwargs)view_url_namer   	__class____name__r   r   r   selfs    </home/dcms/DCMS/lib/python3.12/site-packages/parler/views.pyget_view_urlzViewUrlMixin.get_view_urlI   sP     !! '78O8O7PQ  t))		$++NN    )r   
__module____qualname____doc__r   r"    r#   r!   r   r   (   s    < MOr#   r   c                   <     e Zd ZdZd Zd Zd Z fdZddZ xZ	S )r   ad  
    An enhancement for the :class:`~django.views.generic.DetailView` to deal with translated slugs.
    This view makes sure that:

    * The object is fetched in the proper translation.
    * The slug field is read from the translation model, instead of the shared model.
    * Fallback languages are handled.
    * Objects are not accidentally displayed in their fallback slug, but redirect to the translated slug.

    Example:

    .. code-block:: python

        class ArticleDetailView(TranslatableSlugMixin, DetailView):
            model = Article
            template_name = 'article/details.html'
    c                 &    | j                         |iS )zD
        Allow passing other filters for translated fields.
        )get_slug_field)r    slugs     r!   get_translated_filtersz,TranslatableSlugMixin.get_translated_filtersr   s     ##%t,,r#   c                 *    t        j                         S )z[
        Define the language of the current view, defaults to the active language.
        )r	   get_languager   s    r!   r.   z"TranslatableSlugMixin.get_languagex   s     ''))r#   c                 4    t        | j                               S )z]
        Define the language choices for the view, defaults to the defined settings.
        )r   r.   r   s    r!   get_language_choicesz*TranslatableSlugMixin.get_language_choices~   s     +4+<+<+>??r#   c                    	 t        |   |g|i |S # t        $ rh}t        |j                  |j
                        5  t        |j                  j                               cd d d        cY d }~S # 1 sw Y   nxY wY d }~y d }~ww xY wN)superdispatchFallbackLanguageResolvedr   objectcorrect_languager   get_absolute_url)r    requestr   r   er   s        r!   r4   zTranslatableSlugMixin.dispatch   s}    	R7#G=d=f==' 	R 1+=+=> R4QXX5N5N5PQR R R R	Rs1    	B B#A1"	B+B1A:	6BBc                 ~   || j                         }| j                  | j                     }| j                         }d}d}g }|D ]F  }	 | j	                  |      } |j
                  |fi |j                  |      j                         } n |fdj                  dj                  |            }	t        j                  d      d|j                  j                  j                   iz  }
t#        |
|	z         |r$|D ]  }|j%                  |      st'        ||       |S # t        $ r d}|j                  |       Y w xY w)	z;
        Fetch the object using a translated slug.
        NF)r+   Tz, tried languages: {}z, z,No %(verbose_name)s found matching the queryverbose_name)get_querysetr   slug_url_kwargr0   r,   
translatedlanguagegetr   appendformatjoinr	   gettextmodel_metar<   r   has_translationr5   )r    querysetr+   choicesobjusing_fallbackprev_choiceslang_choicefilters	tried_msgerror_messageprev_choices               r!   
get_objectz TranslatableSlugMixin.get_object   se    ((*H{{4../++-" 	K
 5545@)h))+AAJJ;W[[] 	 ;/66tyy7IJI'//0^_ 4 4 A Ac M -)344   , E&&{3 33DD	E 
7 & 1!%##K01s   ADD<;D<r2   )
r   r$   r%   r&   r,   r.   r0   r4   rS   __classcell__r   s   @r!   r   r   _   s#    $-*@R.r#   r   c                       e Zd ZdZd Zy)r5   z
    An object was resolved in the fallback language, while it could be in the normal language.
    This exception is used internally to control code flow.
    c                      || _         || _        y r2   )r6   r7   )r    r6   r7   s      r!   __init__z!FallbackLanguageResolved.__init__   s     0r#   N)r   r$   r%   r&   rX   r'   r#   r!   r5   r5      s    
1r#   r5   c                   L     e Zd ZdZdZd	 fd	Zd Zd	dZd Z fdZ	d Z
 xZS )
r   z
    Mixin to add language selection support to class based views, particularly create and update views.
    It adds support for the ``?language=..`` parameter in the query string, and tabs in the context.
    r@   c                     t         |   |      }t        |t              r!|j	                  | j                         d       |S )z?
        Assign the language for the retrieved object.
        T)
initialize)r3   rS   
isinstancer   set_current_languager.   )r    rI   r6   r   s      r!   rS   zLanguageChoiceMixin.get_object   s@     #H-f45''(9(9(;'Mr#   c                 n    t        | j                  | j                  | j                  t                    S )zF
        Get the language parameter from the current request.
        )r6   )default)r   r9   query_language_keyget_default_languager6   r   s    r!   r.   z LanguageChoiceMixin.get_language   s1     &LL$114;T;T\b;T;c
 	
r#   c                      y)z
        Return the default language to use, if no language parameter is given.
        By default, it uses the default parler-language.
        Nr'   )r    r6   s     r!   ra   z(LanguageChoiceMixin.get_default_language   s     r#   c                 n    | j                   | j                   j                         S | j                         S )z
        Return the current language for the currently displayed object fields.
        This reads ``self.object.get_current_language()`` and falls back to :func:`get_language`.
        )r6   get_current_languager.   r   s    r!   rd   z(LanguageChoiceMixin.get_current_language   s0    
 ;;";;3355$$&&r#   c                 L    t        |   di |}| j                         |d<   |S )Nlanguage_tabsr'   )r3   get_context_datar   )r    r   contextr   s      r!   rg   z$LanguageChoiceMixin.get_context_data   s-    '*4V4#'#9#9#; r#   c                     | j                         }| j                  r$t        | j                  j                               }ng }t	        | j
                  ||      S )z6
        Determine the language tabs to show.
        )rd   r6   listget_available_languagesr   r9   )r    current_languageavailable_languagess      r!   r   z%LanguageChoiceMixin.get_language_tabs   sM      446;;"&t{{'J'J'L"M"$ /?ATUUr#   r2   )r   r$   r%   r&   r`   rS   r.   ra   rd   rg   r   rT   rU   s   @r!   r   r      s/    
 $
'

Vr#   r   c                   2     e Zd ZdZ fdZ fdZd Z xZS )r   a~  
    Mixin to add translation support to class based views.

    For example, adding translation support to django-oscar::

        from oscar.apps.dashboard.catalogue import views as oscar_views
        from parler.views import TranslatableModelFormMixin

        class ProductCreateUpdateView(TranslatableModelFormMixin, oscar_views.ProductCreateUpdateView):
            pass
    c                 P   t         |   }t        t        j                  dt        j                        }|j                  |ur |       S | j
                  r| j
                  S t        |       }| j                  r| j                  }t        |t        |      S t        |t              S )zX
        Return a ``TranslatableModelForm`` by default if no form_class is set.
        __func__)formfields)rq   )
r3   get_form_classgetattrr   rp   
form_class_get_view_modelrr   r   r   )r    super_methoddefault_methodrF   rr   r   s        r!   rs   z)TranslatableModelFormMixin.get_form_class  s     w- )):~7T7T
 %%7>! &'-;;![[F,U9NW]^^,U9NOOr#   c                 J    t         |          }| j                         |d<   |S )z8
        Pass the current language to the form.
        _current_language)r3   get_form_kwargsget_form_language)r    r   r   s     r!   r{   z*TranslatableModelFormMixin.get_form_kwargs*  s-     (* '+&<&<&>"#r#   c                 "    | j                         S r2   )rd   r   s    r!   r|   z,TranslatableModelFormMixin.get_form_language6  s    ((**r#   )r   r$   r%   r&   rs   r{   r|   rT   rU   s   @r!   r   r     s    
P0+r#   r   c                       e Zd ZdZy)r   z
    Create view that supports translated models.
    This is a mix of the :class:`TranslatableModelFormMixin`
    and Django's :class:`~django.views.generic.edit.CreateView`.
    Nr   r$   r%   r&   r'   r#   r!   r   r   ;       	r#   r   c                       e Zd ZdZy)r   z
    Update view that supports translated models.
    This is a mix of the :class:`TranslatableModelFormMixin`
    and Django's :class:`~django.views.generic.edit.UpdateView`.
    Nr   r'   r#   r!   r   r   E  r   r#   r   c                     | j                   | j                   S t        | d      r"| j                  | j                  j                  S | j	                         j                   S )Nr6   )rF   hasattrr6   r   r=   r   s    r!   rv   rv   O  sP    zzzz	x	 T[[%<{{$$$   "(((r#   N))r&   django.core.exceptionsr   r   django.forms.modelsr   django.httpr   r   django.urlsr   django.utilsr	   django.viewsr
   django.views.generic.editr   parler.formsr   parler.modelsr   parler.utilsr   parler.utils.contextr   parler.utils.viewsr   r   __all__r   r   	Exceptionr5   r   r   
CreateViewr   
UpdateViewr   rv   TranslatableSingleObjectMixinr'   r#   r!   <module>r      s    L 1 >  $   4 . 0 4 0 H4O 4On[ [|1y 1:V :Vz2+!4 2+l	79K9K 		79K9K 		) !4 r#   