a
    Dg                     @   s6   d dl mZ d dlmZ d dlmZ G dd dZdS )    )ContentType)DEFERRED)cached_propertyc                   @   sJ   e Zd ZdZdddZedd Zedd	 Zed
d Ze	dd Z
dS )SpecificMixinz
    Mixin for models that support multi-table inheritance and provide a
    ``content_type`` field pointing to the specific model class, to provide
    methods and properties for retrieving the specific instance of the model.
    FNc           
         s   j }|du rS t|r S |rTtfdd|jjD }|| }jj|j_n|jjj	d}|durfdd|D D ]}t
||t| q~n8|pd  fddj D D ]\}}	|j||	 q|S )a!  
        Return this object in its most specific subclassed form.

        By default, a database query is made to fetch all field values for the
        specific object. If you only require access to custom methods or other
        non-field attributes on the specific object, you can use
        ``deferred=True`` to avoid this query. However, any attempts to access
        specific field values from the returned object will trigger additional
        database queries.

        By default, references to all non-field attribute values are copied
        from current object to the returned one. This includes:

        * Values set by a queryset, for example: annotations, or values set as
          a result of using ``select_related()`` or ``prefetch_related()``.
        * Any ``cached_property`` values that have been evaluated.
        * Attributes set elsewhere in Python code.

        For fine-grained control over which non-field values are copied to the
        returned object, you can use ``copy_attrs`` to specify a complete list
        of attribute names to include. Alternatively, you can use
        ``copy_attrs_exclude`` to specify a list of attribute names to exclude.

        If called on an object that is already an instance of the most specific
        class, the object will be returned as is, and no database queries or
        other operations will be triggered.

        If the object was originally created using a model that has since
        been removed from the codebase, an instance of the base class will be
        returned (without any custom field values or other functionality
        present on the original class). Usually, deleting these objects is the
        best course of action, but there is currently no safe way for Wagtail
        to do that at migration time.
        Nc                 3   s(   | ] }t  |j|jr jntV  qd S N)getattrZattnameZprimary_keypkr   ).0fself V/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/wagtail/models/specific.py	<genexpr>@   s   z-SpecificMixin.get_specific.<locals>.<genexpr>)idc                 3   s   | ]}| j v r|V  qd S r   )__dict__)r	   attrr   r   r   r   M       r   c                 3   s"   | ]\}}| vr||fV  qd S r   r   )r	   kv)excluder   r   r   Q   r   )specific_class
isinstancetupleZ_metaZconcrete_fields_stateZaddingZ_default_managergetr   setattrr   r   items
setdefault)
r   deferredZ
copy_attrsZcopy_attrs_excludemodel_classvaluesZspecific_objr   r   r   r   )r   r   r   get_specific   s&    #
 zSpecificMixin.get_specificc                 C   s   |   S )z
        Returns this object in its most specific subclassed form with all field
        values fetched from the database. The result is cached in memory.
        r"   r   r   r   r   specificW   s    zSpecificMixin.specificc                 C   s   | j ddS )z
        Returns this object in its most specific subclassed form without any
        additional field values being fetched from the database. The result
        is cached in memory.
        T)r   r#   r   r   r   r   specific_deferred_   s    zSpecificMixin.specific_deferredc                 C   s
   | j  S )ad  
        Return the class that this object would be if instantiated in its
        most specific form.

        If the model class can no longer be found in the codebase, and the
        relevant ``ContentType`` has been removed by a database migration,
        the return value will be ``None``.

        If the model class can no longer be found in the codebase, but the
        relevant ``ContentType`` is still present in the database (usually a
        result of switching between git branches without running or reverting
        database migrations beforehand), the return value will be ``None``.
        )cached_content_typer    r   r   r   r   r   h   s    zSpecificMixin.specific_classc                 C   s   t j| jS )z
        Return this object's ``content_type`` value from the ``ContentType``
        model's cached manager, which will avoid a database query if the
        content type is already in memory.
        )r   ZobjectsZ
get_for_idZcontent_type_idr   r   r   r   r&   y   s    z!SpecificMixin.cached_content_type)FNN)__name__
__module____qualname____doc__r"   r   r$   r%   r   propertyr&   r   r   r   r   r      s   
J


r   N)Z"django.contrib.contenttypes.modelsr   Zdjango.db.modelsr   Zdjango.utils.functionalr   r   r   r   r   r   <module>   s   