Django

Django

Explore django code snippets and tutorials

Django

Django custom select widgets for select2 js

Django custom select widgets for select2 js

python
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from django.forms.widgets import Select, SelectMultiple
from django.utils.safestring import mark_safe

class CustomSelectWithQueryset(Select):
    '''
    Works with ModelChoiceField
    '''
    def __init__(self, queryset=None, attrs=None, choices=(), ajax_url=None):
        super().__init__(attrs=attrs, choices=choices)
        self.queryset = queryset
        self.ajax_url = ajax_url

    def render(self, name, value, attrs=None, renderer=None):
        if attrs is None:
            attrs = {}
        # Set the id attribute based on the field name
        attrs['id'] = f'id_{name}'
        
        # Generate options from the queryset
        if self.queryset is not None:
            choices = [(obj.pk, str(obj)) for obj in self.queryset]
        else:
            choices = self.choices

        self.choices = choices
        print(self.choices)
        output = super().render(name, value, attrs, renderer)
        ajax_url = self.ajax_url
        # Add the Select2 initialization script
        script = f'''
            <script type="text/javascript">
                (function($) {{
                    $(document).ready(function() {{
                        $('#{attrs['id']}').select2({{
                            ajax: {{
                                url: '{ajax_url}',
                                dataType: 'json',
                                delay: 250,
                                data: function (params) {{
                                    return {{
                                        search: params.term,
                                        type: 'public'
                                    }};
                                }},
                                processResults: function (data) {{
                                    return {{
                                        results: $.map(data.results, function (item) {{
                                            return {{
                                                id: item.id,
                                                text: item.text
                                            }};
                                        }})
                                    }};
                                }},
                                cache: true
                            }},
                            placeholder: "Select option",
                            allowClear: true,
                        }});
                    }});
                }})(jQuery);
            </script>
        '''
        
        return mark_safe(output + script)
    


class CustomSelectMultipleWithUrl(SelectMultiple):
    '''
    Works with ModelMultipleChoiceField
    '''
    def __init__(self, queryset=None, attrs=None, choices=(), ajax_url=None):
        super().__init__(attrs=attrs, choices=choices)
        self.queryset = queryset
        self.ajax_url = ajax_url

    def render(self, name, value, attrs=None, renderer=None):
        if attrs is None:
            attrs = {}
        # Set the id attribute based on the field name
        attrs['id'] = f'id_{name}'
        
        # Generate options from the queryset
        if self.queryset is not None:
            choices = [(obj.pk, str(obj)) for obj in self.queryset]
        else:
            choices = self.choices

        self.choices = choices
        output = super().render(name, value, attrs, renderer)
        
        # Add the Select2 initialization script with dynamic AJAX URL
        ajax_url = self.ajax_url
        script = f'''
            <script type="text/javascript">
                (function($) {{
                    $(document).ready(function() {{
                        $('#{attrs['id']}').select2({{
                            ajax: {{
                                url: '{ajax_url}',
                                dataType: 'json',
                                delay: 250,
                                data: function (params) {{
                                    return {{
                                        search: params.term,
                                        type: 'public'
                                    }};
                                }},
                                processResults: function (data) {{
                                    return {{
                                        results: $.map(data.results, function (item) {{
                                            return {{
                                                id: item.id,
                                                text: item.text
                                            }};
                                        }})
                                    }};
                                }},
                                cache: true
                            }},
                            placeholder: "Select options",
                            allowClear: true,
                            multiple: true  // Enable multiple selection
                        }});
                    }});
                }})(jQuery);
            </script>
        '''
        
        return mark_safe(output + script)
Django

Django json decimal encoder

<p>Convert decimal to string for json&nbsp; file</p>

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import json

class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        # 👇️ if passed in object is instance of Decimal
        # convert it to a string
        if isinstance(obj, Decimal):
            return str(obj)
        # 👇️ otherwise use the default behavior
        return json.JSONEncoder.default(self, obj)


def write_json_data(data, filename):
    with open("{}.json".format(filename), "w", encoding="utf-8") as f:
        # json.dump(data, f, ensure_ascii=False, indent=4, cls=DecimalEncoder)
        json.dump(data, f, ensure_ascii=False, cls=DecimalEncoder)