django-gm2m icon indicating copy to clipboard operation
django-gm2m copied to clipboard

Default Formfield not available, Workaround failed

Open tkhyn opened this issue 8 years ago • 7 comments
trafficstars

Original report by lb1c (Bitbucket: lb1c, GitHub: lb1c).


I tried to simply use the GM2M Field in the django admin app. I saw the future warning about the non-support and looked for more info.

I need to able to manage these relations in the admin app with a defined subset of items, basically models from my custom app.

I tried to workaround the limitation by defining a formfield with data on my own.

#!python

# models.py
class GroupPermission(models.Model):
    group = models.OneToOneField(Group)
    models_access = GM2MField()

# forms.py
class GroupPermissionForm(forms.ModelForm):
    models_access = forms.MultipleChoiceField(
            widget=FilteredSelectMultiple('Model Fields', False),
            required=False,
            label=_('Permitted Models'),
    )
    def __init__(self, *args, **kwargs):
        super(GroupPermissionForm, self).__init__(*args, **kwargs)

        # get a list of models and fields
        models = apps.get_app_config('myapp').get_models()
model_choices = []

        for model in models:
            m_name = model.__name__
            m_verbose_name = model._meta.verbose_name if hasattr(model._meta, 'verbose_name') \
                else m_name

            model_choices.append((m_name, m_verbose_name))
        self.fields['models_access'].choices = model_choices

But this crashes the template rendering of the admin app:

#!python

Template error:
In template /var/venv/lib/python3.5/site-packages/django/contrib/admin/templates/admin/change_form.html, error at line 33
   'GM2MManager' object is not iterable   23 : {% endblock %}
   24 : {% endif %}
   25 : 
   26 : {% block content %}<div id="content-main">
   27 : {% block object-tools %}
   28 : {% if change %}{% if not is_popup %}
   29 :   <ul class="object-tools">
   30 :     {% block object-tools-items %}
   31 :     <li>
   32 :         {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
   33 :         <a href=" {% add_preserved_ filters history_url %}" class="historylink">{% trans "History" %}</a>
   34 :     </li>

Could you provide any hint on how to achieve this or what are the plans for supporting formfields for gm2m relations?

tkhyn avatar May 15 '17 08:05 tkhyn

Original comment by lb1c (Bitbucket: lb1c, GitHub: lb1c).


Related to 9ffd371

tkhyn avatar May 15 '17 08:05 tkhyn

Original comment by Thomas Khyn (Bitbucket: tkhyn, GitHub: tkhyn).


Hi,

As I have no use of a GM2MFormField for the moment (and not much spare time to dedicate to gm2m development) it's unlikely it'll be officially supported any time soon, unless somebody comes up with a good looking PR !

As per your problem, it comes from the fact that a MultipleChoiceField would need some tuning to work in association with a GM2MField, as it does not know how to retrieve / set the values on a GM2MField. The only way to resolve this is to create a specific GM2MFormField derived from MultipleChoiceField that can correctly retrieve / set the values associated with a GM2MField ... and this basically means adding form field support for gm2m relations ...

Sorry I cannot help more. If I need that in the near future I'll definitely give it a go but I have not much time for this at the moment.

tkhyn avatar May 15 '17 09:05 tkhyn

Original comment by lb1c (Bitbucket: lb1c, GitHub: lb1c).


I see your point and i'm not demanding immediate support for free :smiley: I'll try sorting it out by writing a custom FormField wich will do the proper data en/decoding for my use cases. But this will be pretty non-portable so i wont create a PR for that.

I'll keep watching this issue in case you change your mind due to your personal needs. Till then, keep up the good work :+1:

tkhyn avatar May 15 '17 09:05 tkhyn

Original comment by Thomas Khyn (Bitbucket: tkhyn, GitHub: tkhyn).


No problem, sorry again I can't help at the moment. Even if you come up with a not-so-portable solution, that would be great if you could share the way you made it for future reference. I'll leave this ticket open anyway for now as a reminder that this needs to be addressed at some point (it's the last missing feature listed in the 'future improvements' section after all !).

tkhyn avatar May 15 '17 10:05 tkhyn

Original comment by tehfink (Bitbucket: tehfink, GitHub: tehfink).


@lb1c : I too would be interested in your solution!

tkhyn avatar Aug 16 '17 03:08 tkhyn

Hi guys. Have anybody any progress of this? Thx

eriktelepovsky avatar Nov 30 '20 21:11 eriktelepovsky

Hello.

I have 2 possible solutions for this feature:

  1. Django ModelAdmin comes with one handy feature: autocomplete_fields. It can be used for M2M relations. It is of course limited to a single Model relationship but I believe this is the way how to achieve a GM2MFormField in admin. My idea is to inherit and override the default functionality and instead of looking for instances of specific model defined in m2m relationship it could browse instances of all defined ModelAdmins in the app. The other issue which needs to be solved is the serialisation of the form field value because it can't contain primary keys only, but the content type as well. For instance something like myapp.MyFirstModel:123, myapp2.MySecondModel:321 ...

  2. instead of creating custom form field maybe we can use custom admin model inlines. The table would consist objects containing 2 form fields: selectbox/dropdown with content types + form field for object PK.

eriktelepovsky avatar Nov 28 '21 17:11 eriktelepovsky