
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
U
    SW                     @   s   d Z ddlT 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 e	 Z
i ZG dd	 d	eZG d
d deeeZdd ZG dd deZG dd deZG dd deZdS )a  
Provide a "Generic ForeignKey", similar to Django.  A "GFK" is composed of two
columns: an object ID and an object type identifier.  The object types are
collected in a global registry (all_models), so all you need to do is subclass
``gfk.Model`` and your model will be added to the registry.

Example:

class Tag(Model):
    tag = CharField()
    object_type = CharField(null=True)
    object_id = IntegerField(null=True)
    object = GFKField('object_type', 'object_id')

class Blog(Model):
    tags = ReverseGFK(Tag, 'object_type', 'object_id')

class Photo(Model):
    tags = ReverseGFK(Tag, 'object_type', 'object_id')

tag.object -> a blog or photo
blog.tags -> select query of tags for ``blog`` instance
Blog.tags -> select query of all tags for Blog instances
    )*)	BaseModel)Model)SelectQuery)UpdateQuery)with_metaclassc                       s   e Zd Z fddZ  ZS )r   c                    s,   t t| | |||} |dkr(t|  | S )N)Z_metaclass_helper_r   )superr   __new__
all_modelsadd)clsnamebasesZattrs	__class__ @/opt/alt/python38/lib64/python3.8/site-packages/playhouse/gfk.pyr	   '   s    
zBaseModel.__new__)__name__
__module____qualname__r	   __classcell__r   r   r   r   r   &   s   r   c                   @   s   e Zd ZdS )r   N)r   r   r   r   r   r   r   r   -   s   r   c                 C   s4   | t kr*tD ]}|jj| kr|t | <  q*qt | S N)table_cacher
   _metadb_tableget)tbl_namemodelr   r   r   	get_model0   s    r   c                   @   s@   e Zd ZdZdd Zedd Zedd Zdd	 Zd
d Z	dS )BoundGFKFieldmodel_class	gfk_fieldc                 C   s   || _ || _d S r   r    )selfr!   r"   r   r   r   __init__;   s    zBoundGFKField.__init__c                 C   sB   | j jj}t| jj| jjf}|D ]\}}|t| s" dS q"dS NTF)r!   r   indexessetr"   model_type_fieldmodel_id_field)r#   r&   fieldsZindexed_columnsZ	is_uniquer   r   r   unique?   s    
zBoundGFKField.uniquec                 C   s>   | j jj}t|tr:t| jj| jjf}|t|j	 s:dS dS r%   )
r!   r   primary_key
isinstanceZCompositeKeyr'   r"   r(   r)   field_names)r#   Zpkr*   r   r   r   r,   I   s    

zBoundGFKField.primary_keyc                 C   s<   | j j}|j| jj }|j| jj }||jjk|| k@ S r   )r!   r   r*   r"   r(   r)   r   _get_pk_value)r#   othermeta
type_fieldid_fieldr   r   r   __eq__S   s    

zBoundGFKField.__eq__c                 C   s@   t |}|jj| jj }|jj| jj }||jjk|| k@ S r   )typer   r*   r"   r(   r)   r   r/   )r#   r0   Z	other_clsr2   r3   r   r   r   __ne__[   s    

zBoundGFKField.__ne__N)
r   r   r   	__slots__r$   propertyr+   r,   r4   r6   r   r   r   r   r   8   s   
	
	r   c                   @   s0   e Zd ZdddZdd Zddd	Zd
d ZdS )GFKFieldobject_type	object_idc                 C   s$   || _ || _d| j | jf| _d S )N.)r(   r)   joinatt_name)r#   r(   r)   r   r   r   r$   e   s    zGFKField.__init__c                 C   sh   |j }|| jrd|| jrd|| j }t|}|s@td| | |jj	|| j k}| S d S )Nz-Model for table "%s" not found in GFK lookup.)
_datar   r(   r)   r   AttributeErrorselectwherer   r,   )r#   instancedatar   r!   Zqueryr   r   r   get_objk   s    
zGFKField.get_objNc                 C   sB   |r8| j |jkr*| |}|r*||j| j < |j| j S t|| S r   )r>   
_obj_cacherE   r   r   )r#   rC   instance_typeZrel_objr   r   r   __get__w   s    
zGFKField.__get__c                 C   s0   ||j | j< |jj|j| j< | |j| j< d S r   )rF   r>   r   r   r?   r(   r/   r)   )r#   rC   valuer   r   r   __set__   s    zGFKField.__set__)r:   r;   )N)r   r   r   r$   rE   rH   rJ   r   r   r   r   r9   d   s     

	r9   c                   @   s(   e Zd Zd
ddZdddZdd	 ZdS )
ReverseGFKr:   r;   c                 C   s&   || _ |jj| | _|jj| | _d S r   )r!   r   r*   r(   r)   )r#   r   r(   r)   r   r   r   r$      s    zReverseGFK.__init__Nc                 C   sJ   |r,| j  | j|jjk| j| k@ S | j  | j|jjkS d S r   )r!   rA   rB   r(   r   r   r)   r/   )r#   rC   rG   r   r   r   rH      s    

zReverseGFK.__get__c                    s   |j j}| }t|trL|j jkrLt j j| j|i	|j
  nVtt fdd|r|D ],}t| jj| t| jj| |  qfntd| d S )Nc                    s   t |  jS r   )r-   r!   )ir#   r   r   <lambda>       z$ReverseGFK.__set__.<locals>.<lambda>z&ReverseGFK field unable to handle "%s")r   r   r/   r-   r   r!   r   r(   r)   rB   Z_whereexecuteallmapsetattrr   Zsave
ValueError)r#   rC   rI   ZmtvZmivobjr   rM   r   rJ      s&    

  
zReverseGFK.__set__)r:   r;   )N)r   r   r   r$   rH   rJ   r   r   r   r   rK      s
     

rK   N)__doc__Zpeeweer   Z
_BaseModelr   Z_Modelr   r   r   r'   r
   r   r   objectr   r9   rK   r   r   r   r   <module>   s   ,"