7
votes

Attribuez des objets utilisateur à un groupe lors de la modification de groupe-objet dans Django Admin

Dans la vue d'administration Django par défaut pour l'objet utilisateur (Modifier l'utilisateur), vous pouvez modifier les adhésions de groupe de l'utilisateur. Et si je voulais cela l'autre moyen aussi? C'est à dire. Dans la première page d'édition de groupe, vous pouvez sélectionner les utilisateurs qui appartiennent au groupe édité.

Comme je le vois, Django n'a pas de mappage multiple de groupe à un objet utilisateur qui le rend impossible (?) de mettre en œuvre une modernité classe pour ce cas particulier. Si je pouvais effectuer une classe modèle supplémentaire de groupe de groupe et l'utiliser dans le domaine balnéomany de Modèle de groupe de Django en tant qu'attribut terrestre, il pourrait y avoir un moyen.

Toute idée, est-ce possible de mettre en œuvre avec des tours de modeladmin ou Dois-je juste faire une vue personnalisée pour éditer des groupes?

J'ai vérifié ces deux autres questions, mais elles ne font pas tout à fait la même chose:

AssIquage d'un groupe lors de l'ajout de l'utilisateur à admin

et

Afficher l'adhésion à l'administrateur

mis à jour: La réponse de Chris était presque là. :) Le groupe a une référence aux utilisateurs définis, mais elle s'appelle user_set , pas utilisateurs . Donc, ce sont les modifications que j'ai faite: xxx

et xxx


0 commentaires

4 Réponses :


3
votes

yourapp / admin.py xxx


3 commentaires

Merci, cela a fait l'affaire! J'ai dû le modifier un peu, mais il s'agissait essentiellement de la solution.


Le code ci-dessus a fonctionné pour moi. Seul le changement que je devais faire était de changer auto.instance.utilisateur.All () à auto.Instance.user_set.all ()


Ce code ne fonctionne pas, dans la mesure où lorsque vous ajoutez des utilisateurs au groupe, et enregistrez vos modifications. La solution par TOMKA ci-dessous fonctionne avec Remee Django et Python



4
votes

La méthode de sauvegarde ci-dessus ne fonctionnera pas si vous ajoutez un nouveau groupe et ajoute simultanément des utilisateurs au groupe. Le problème est que le nouveau groupe ne sera pas enregistré (l'administrateur utilise COMTT = FALSE) et n'aura pas une clé primaire. Étant donné que le but de sauvegarde_m2m () consiste à autoriser la vue d'appel à gérer des objets de sauvegarde de M2M, j'ai fait un objet Enregistrer qui enveloppe l'ancienne méthode Save_M2M dans une nouvelle méthode.

def save(self, commit=True):
    group = super(GroupAdminForm, self).save(commit=commit)

    if commit:
        group.user_set = self.cleaned_data['users']
    else:
        old_save_m2m = self.save_m2m
        def new_save_m2m():
            old_save_m2m()
            group.user_set = self.cleaned_data['users']
        self.save_m2m = new_save_m2m
    return group


1 commentaires

Je peux confirmer que c'est la bonne façon de gérer les relations M2M.



0
votes

Voici une approche plus simple qui utilise des objets inlinemodeladmin de Django ( répondit ici sur QUBANSHI.CC )

from django.contrib.auth.admin import GroupAdmin
from django.contrib.auth.models import User, Group

class UserSetInline(admin.TabularInline):
    model = User.groups.through
    raw_id_fields = ('user',)  # optional, if you have too many users

class MyGroupAdmin(GroupAdmin):
    inlines = [UserSetInline]

# unregister and register again
admin.site.unregister(Group)
admin.site.register(Group, MyGroupAdmin)


0 commentaires

1
votes

Je suis sur Django 2.1 et utilisais la solution postée par Chris, mais comme expliqué par Cédric, cela ne fonctionnerait pas lorsque lorsqu'un nouveau groupe a été ajouté et que des utilisateurs simultanément ont été ajoutés au nouveau groupe. Malheureusement, son code n'a pas aidé non plus, mais je pourrais le faire fonctionner à l'aide de cette version modifiée ci-dessous.

edit fort>: J'ai inclus la suggestion de l'utilisateur am70 em> ( Merci!) et utilisé get_user_model () code>. Ce code continue de fonctionner avec Django 3.1 et a été testé avec Python 3.6, 3.7 et 3.8. P>

from django import forms
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth import get_user_model ; User = get_user_model()
from django.contrib.auth.models import Group

class GroupAdminForm(forms.ModelForm):
    users = forms.ModelMultipleChoiceField(
        queryset=User.objects.all(), 
        required=False,
        widget=FilteredSelectMultiple(
            verbose_name=_('Users'),
            is_stacked=False
        )
    )

    class Meta:
        model = Group

    def __init__(self, *args, **kwargs):
        super(GroupAdminForm, self).__init__(*args, **kwargs)

        if self.instance and self.instance.pk:
            self.fields['users'].initial = self.instance.users.all()


class GroupAdmin(admin.ModelAdmin):
    form = GroupAdminForm

    def save_model(self, request, obj, form, change):
        super(GroupAdmin, self).save_model(request, obj, form, change)
        if 'users' in form.cleaned_data:
            form.instance.user_set.set(form.cleaned_data['users'])


admin.site.unregister(Group)
admin.site.register(Group, GroupAdmin)


2 commentaires

Celui-ci est le seul qui travaille sur Django 3. Je recommande également de ne pas importer utilisateur mais de django.contrib.auth importe get_user_model; Utilisateur = get_user_model ()


C'est une bonne suggestion, merci. Je l'ai inclus dans la réponse.