3
š(ƒhû  ã               @   s8   d dl mZ d dlmZ d dlmZ G dd„ deƒZdS )é    )ÚPermissionDenied)Ú
force_text)Úescapec               @   sT   e Zd ZdZdZi ZdZdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ ZdS )ÚLookupChannelaâ  
    Subclass this, setting the model and implementing methods to taste.

    Attributes:
        model (Model): The Django Model that this lookup channel will search for.
        plugin_options (dict): Options passed to jQuery UI plugin that are specific to this channel.
        min_length (int): Minimum number of characters user types before a search is initiated.

            This is passed to the jQuery plugin_options.
            It is used in jQuery's UI when filtering results from its own cache.

            It is also used in the django view to prevent expensive database queries.
            Large datasets can choke if they search too often with small queries.
            Better to demand at least 2 or 3 characters.
    Né   c             C   s&   d| j  |i}| jjjf |Žj| j ƒS )aç  
        Return a QuerySet searching for the query string `q`.

        Note that you may return any iterable so you can return a list or even use yield and turn this
        method into a generator.

        Args:
            q (str, unicode): The query string to search for.
            request (Request): This can be used to customize the search by User or to use additional GET variables.

        Returns:
            (QuerySet, list, generator): iterable of related_models
        z%s__icontains)Zsearch_fieldÚmodelÚobjectsÚfilterZorder_by)ÚselfÚqÚrequestÚkwargs© r   úK/tmp/pip-install-q3hcpn_q/django-ajax-selects/ajax_select/lookup_channel.pyÚ	get_query   s    zLookupChannel.get_queryc             C   s   t t|ƒƒS )aß  The text result of autocompleting the entered query.

        For a partial string that the user typed in, each matched result is here converted to the fully completed text.

        This is currently displayed only for a moment in the text field after the user has selected the item.
        Then the item is displayed in the item_display deck and the text field is cleared.

        Args:
            obj (Model):
        Returns:
            str: The object as string
        )r   r   )r
   Úobjr   r   r   Ú
get_result-   s    zLookupChannel.get_resultc             C   s   t t|ƒƒS )z©(HTML) Format item for displaying in the dropdown.

        Args:
            obj (Model):
        Returns:
            str: formatted string, may contain HTML.
        )r   r   )r
   r   r   r   r   Úformat_match<   s    zLookupChannel.format_matchc             C   s   t t|ƒƒS )z¹ (HTML) format item for displaying item in the selected deck area.

        Args:
            obj (Model):
        Returns:
            str: formatted string, may contain HTML.
        )r   r   )r
   r   r   r   r   Úformat_item_displayF   s    z!LookupChannel.format_item_displayc                s>   | j jjj‰ ‡ fdd„|D ƒ}| j jj|ƒ‰‡fdd„|D ƒS )av  This is used to retrieve the currently selected objects for either ManyToMany or ForeignKey.

        Note that the order of the ids supplied for ManyToMany fields is dependent on how the
        objects manager fetches it.
        ie. what is returned by `YourModel.{fieldname}_set.all()`

        In most situations (especially postgres) this order is indeterminate -- not the order that you originally
        added them in the interface.
        See :doc:`/Ordered-ManyToMany` for a solution to this.

        Args:
            ids (list): list of primary keys
        Returns:
            list: list of Model objects
        c                s   g | ]}ˆ |ƒ‘qS r   r   )Ú.0Úpk)Úpk_typer   r   ú
<listcomp>b   s    z-LookupChannel.get_objects.<locals>.<listcomp>c                s   g | ]}|ˆ krˆ | ‘qS r   r   )r   Zaid)Úthingsr   r   r   d   s    )r   Z_metar   Z	to_pythonr   Zin_bulk)r
   Úidsr   )r   r   r   Úget_objectsP   s    zLookupChannel.get_objectsc             C   s.   ddl m} |jj|ƒ}|jd|j|jf ƒS )al  Check if the user has permission to add a ForeignKey or M2M model.

        This enables the green popup + on the widget.
        Default implentation is the standard django permission check.

        Args:
            user (User)
            other_model (Model): the ForeignKey or M2M model to check if the User can add.
        Returns:
            bool
        r   )ÚContentTypez	%s.add_%s)Z"django.contrib.contenttypes.modelsr   r   Zget_for_modelZhas_permZ	app_labelr   )r
   ÚuserZother_modelr   Úctyper   r   r   Úcan_addf   s    zLookupChannel.can_addc             C   s   |j jst‚dS )až  By default only request.user.is_staff have access.

        This ensures that nobody can get your data by simply knowing the lookup URL.

        This is called from the ajax_lookup view.

        Public facing forms (outside of the Admin) should implement this to allow
        non-staff to use this LookupChannel.

        Args:
            request (Request)
        Raises:
            PermissionDenied
        N)r   Zis_staffr   )r
   r   r   r   r   Ú
check_authv   s    zLookupChannel.check_auth)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Zplugin_optionsZ
min_lengthr   r   r   r   r   r   r    r   r   r   r   r      s   

r   N)Zdjango.core.exceptionsr   Zdjango.utils.encodingr   Zdjango.utils.htmlr   Úobjectr   r   r   r   r   Ú<module>   s   