<s> import logging <EOL> from import_export import fields <EOL> logger = logging . getLogger ( __name__ ) <EOL> class ThroughField ( fields . Field ) : <EOL> def __init__ ( <EOL> self , through_model , through_from_field_name , through_to_field_name , <EOL> attribute = None , column_name = None , widget = None , <EOL> readonly = False <EOL> ) : <EOL> """<STR_LIT>""" <EOL> self . through_model = through_model <EOL> self . through_from_field_name = through_from_field_name <EOL> self . through_to_field_name = through_to_field_name <EOL> super ( ) . __init__ ( attribute , column_name , widget , readonly ) <EOL> def save ( self , obj , data ) : <EOL> if not self . readonly : <EOL> value = data . get ( self . column_name ) <EOL> current = set ( self . widget . clean ( value ) ) <EOL> old_objs = set ( [ <EOL> getattr ( i , self . through_to_field_name ) for i in <EOL> self . through_model . objects . filter ( <EOL> ** { self . through_from_field_name : obj } <EOL> ) . select_related ( <EOL> self . through_to_field_name <EOL> ) <EOL> ] ) <EOL> to_add = current - old_objs <EOL> to_remove = old_objs - current <EOL> to_add_list = [ ] <EOL> for i in to_add : <EOL> logger . info ( '<STR_LIT>' . format ( <EOL> i . pk , self . through_model , obj . pk <EOL> ) ) <EOL> to_add_list . append ( self . through_model ( <EOL> ** { <EOL> self . through_from_field_name : obj , <EOL> self . through_to_field_name : i <EOL> } <EOL> ) ) <EOL> if to_add_list : <EOL> self . through_model . objects . bulk_create ( to_add_list ) <EOL> if to_remove : <EOL> logger . warning ( '<STR_LIT>' . format ( <EOL> self . through_model , obj . pk , [ i . pk for i in to_remove ] <EOL> ) ) <EOL> self . through_model . objects . filter ( <EOL> ** { <EOL> self . through_from_field_name : obj , <EOL> '<STR_LIT>' . format ( self . through_to_field_name ) : to_remove <EOL> } <EOL> ) . delete ( ) </s>
