Last active
November 22, 2023 11:25
-
-
Save quxf2012/b1827d2bf02322c2779e8309ba089163 to your computer and use it in GitHub Desktop.
django admin manytomany field list_edit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
base https://gist.github.com/jdklub/9261959 | |
usage: | |
@admin.register(XxxModel) | |
class XxxModelAdmin(ModelMultipleListEdit, admin.ModelAdmin): | |
m_list_editable={ | |
"field": { | |
"queryset": field_queryset, | |
"index": -1 # list_display index; insert if index exists else append | |
} | |
} | |
""" | |
from django import forms | |
from django.forms.utils import flatatt | |
from django.utils.safestring import mark_safe | |
__all__ = ['ModelMultipleListEdit'] | |
class StyleableCheckboxSelectMultiple(forms.CheckboxSelectMultiple): | |
def __init__(self, attrs=None, ul_attrs=None): | |
self.ul_attrs = ul_attrs | |
super().__init__(attrs) | |
def render(self, *args, **kwargs): | |
html = super().render(*args, **kwargs) | |
final_attrs = self.build_attrs(self.ul_attrs) | |
return mark_safe(html.replace('<ul>', '<ul%s>' % flatatt(final_attrs))) | |
class ModelMultipleListEdit: | |
""" | |
m_list_editable={ | |
"field": { | |
"queryset": field_queryset, | |
"index": -1 # list_display index, insert if index exist else append | |
} | |
} | |
""" | |
m_list_editable = None | |
def get_changelist_form(self, request, **kwargs): | |
if not self.m_list_editable: | |
return super().get_changelist_form(request, **kwargs) | |
# dynamic create Form | |
cls_dict = {} | |
for field, v in self.m_list_editable.items(): | |
queryset = v['queryset'] | |
# dynamic create ManyToManyField form field | |
cls_dict[field] = forms.ModelMultipleChoiceField(queryset=queryset, widget=StyleableCheckboxSelectMultiple(ul_attrs={"style": "height:80px; overflow-y:scroll;"}), required=False) | |
cls = type('CloudAppForm', (forms.ModelForm,), cls_dict) | |
return cls | |
def get_changelist_instance(self, request): | |
changeList = super().get_changelist_instance(request) | |
if not self.m_list_editable: | |
return changeList | |
# injection ManyToManyField to list_display list_editable ; | |
# use to skip ManyToManyField check; | |
list_display = list(self.list_display) | |
list_editable = list(self.list_editable) | |
for field, v in self.m_list_editable.items(): # key | |
if field not in list_display: | |
if 'index' in v: # 0 is valid value | |
list_display.insert(int(v['index']), field) | |
else: | |
list_display.append(field) | |
if field not in list_editable: | |
list_editable.append(field) | |
self.list_display = list_display | |
self.list_editable = tuple(list_editable) | |
# fix first request display | |
changeList.list_display = list_display | |
if changeList.is_popup: | |
changeList.list_editable = () | |
else: | |
changeList.list_editable = list_editable | |
# fix first request display | |
return changeList |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment