2017-01-10 10 views
3

こんにちは、私はDjango 1.9を使用しています。作成または保存時にグループ化するユーザーを追加しようとしています。 user.groupsまたはgroups.user_set.addのいずれかを使用しても動作しません。下記の保存前と保存後のものを混在させてください。Djangoでグループ保存するユーザーを追加する1.9

これらの答えは私のために働いていない、とこれはだまされやすい人ではありません。 Adding user to group on creation in Django
Adding a user to a group in django
Add users to groups in Django

私は前後の保存ハンドラの両方で両方の方法を試してみました。

@receiver(pre_save, sender=User) 
def user_presave_handler(sender, instance, **kwargs): 
    if instance.is_staff and not instance.is_superuser: 
     # Grant all permissions 
     try: 
      instance.groups.add(Group.objects.get(name='staff_user')) 
     except Group.DoesNotExist: 
      pass 

@receiver(post_save, sender=User) 
def user_postsave_handler(sender, instance, **kwargs): 
    if instance.is_staff and not instance.is_superuser: 
     try: 
      g = Group.objects.get(name='staff_user') 
     except Group.DoesNotExist: 
      pass 
     else: 
      g.user_set.add(instance) 
      g.save() 

ここではどの方法を使用したかを試してみました。私はテストで複数の方法を使用しません。ユーザー管理ページの保存ボタンを押すと、そのユーザーはグループのように表示されません。

Iハンドラが呼び出さなっていることをダブルチェック、ユーザー・ロジックが正しいか、など

は私が間違ってやっている何か、または古い方法を破るために1.9に変更されているものはありますか?

ありがとうございます!

編集:多分私はそれが間違って作られたものの、

group, __ = Group.objects.get_or_create(name='staff_user') 

permissions = Permission.objects.all() 
for p in permissions: 
    group.permissions.add(p) 
group.save() 

私はそれをデバッグしていると、グループは間違いなく存在するので、それは適用されません。求めて人のために は、グループは、このように作成されましたか?

+0

'instance.groups.add'は機能します...グループが存在していますか? – TheWaveLad

+0

受信機にブレークポイントを追加して実際に何が起きているのかを知ることをお勧めします( 'import pdb; pdb.set_trace()') –

+0

正しく見えます。手動でメソッドを呼び出そうとしたことがありますか? – Jann

答えて

2

私はこのことに関連していると思います:Issue with ManyToMany Relationships not updating inmediatly after save。 Somethereは、それがまだ1.10に入っているというコメントを報告しています。

管理者の[ユーザーの追加]ページでグループを選択することもできます。ユーザーを保存するとき、その後、次の処理が行われます。

  1. ユーザーが
  2. を保存されているポストセーブ信号が発生し、そしてあなたは、ユーザーの
  3. すべてのグループであるグループにユーザーを追加消去されました
  4. ユーザーの追加ページで選択されたグループがユーザーに追加されます。

明らかにm2m_changed信号を使用できます。私はそれを使ったことがないが、私はこのような何かが動作するはずだと思う:

from django.db.signals import m2m_changed 

@receiver(m2m_changed, sender=User.groups.through) 
def user_groups_changed_handler(sender, instance, action, **kwargs): 
    if action == 'post_add' and instance.is_staff and not instance.is_superuser: 
     if not instance.groups.filter(name='staff_user').exists(): 
      try: 
       g = Group.objects.get(name='staff_user') 
      except Group.DoesNotExist: 
       pass 
      else: 
       instance.groups.add(g) 

これは、それ以外の場合は多少異なって見えるために起こって、信号が受信instanceがユーザーであると仮定しています。アクションのチェックと、グループがすでに追加されているかどうかのチェックは、無限ループを防ぐためのものです。送信者は、多対多の関係のための隠された「スルー」表User.groups.throughです。

+0

これはすばらしく、私たちに一歩近づけます。残念ながら、信号はM2Mが変更されたときにのみ送信されます。つまり、自動的にではなく、別のグループにユーザーを追加するときに機能します。 –

+0

調査すると、post_removeはあなたの言ったように、変更されているかどうかにかかわらず送信されます。つまり、if(action == 'post_save'またはaction == 'post_remove')とinstance.is_suaffではなく、instance.is_superuser: ''が現在動作しているようだが、私はさらにテストするだろう。 –

+0

post_removeをトピックについての今後のGoogleの答え、感謝! 23時間以内の恩恵 –

関連する問題