1

モデルの管理者リストからユーザーが自滅するのを防ぐ必要があります。

class Organization(models.Model):       
    administrators = models.ManyToManyField(User, blank=True, null=True, help_text=_('Administrators are people that manage the organization'))

    def save(self, *args, **kwargs):
        # --- some specific code here ---
        super(Organization, self).save(*args, **kwargs)
        if self.user_id not in self.administrators.values_list('id', flat=True):
            self.administrators.add(self.user)
            # super(Organization, self).save(*args, **kwargs)
            self.save()                
            # assert False, self.administrators.all() # <- it works, if assert goes here

わかりました、ここでキャストされた黒魔術かもしれません。信号を試してみましょうpost_save:

def organization_post_save(sender, instance, created, **kwargs):
    if instance.user_id not in instance.administrators.all().values_list('id', flat=True):
        instance.administrators.add(instance.user)
        instance.save()
        # assert False, '?'

アサーションが発生した場合にのみ、管理者リストにユーザーを追加します。わかりました、黒魔術が再び発生した可能性があります。試してみましょう:

def organization_m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs):
    if instance.user_id not in instance.administrators.all().values_list('id', flat=True):
        instance.administrators.add(instance.user_id)

m2m_changed.connect(organization_m2m_changed, sender=Organization.administrators.through)

もちろん、maximum recursion depth exceeded。どうしたの?この痛みは止められません:(

UPD1

BEFORE m2m リレーションpost_saveと呼ばれるメソッドが保存されたため、競合状態に陥り、新しいデータが空のフォーム データに置き換えられたようです。悪い解決策は次のとおりです。

def organization_m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs):

    if not instance.administrators.filter(id=instance.user_id).exists():
        if action.startswith('post_'):
            instance.administrators.add(instance.user)

モデルに関するすべての作業が完了した後、Django が発するシグナルを知りたいのですが。

PS魔法はありません。:(

UPD2 ライライアン

フォーム.py

class OrganizationEditForm(forms.ModelForm):    
    class Meta:
        model = Organization
        exclude = ['user']
        widgets = floppyforms_widgets(Organization)

ビュー.py

@login_required
def edit_organization(request, organization_id=None):
    user = request.user
    c = Context({'user': user})

    instance = get_object_or_404(Organization, id=organization_id) if organization_id else Organization(user=user)
    form = OrganizationEditForm(request.POST or None, request.FILES or None, instance=instance)

    if form.is_valid():
        form.save()
        messages.success(request, _('Organization saved successfully'))
        return HttpResponseRedirect(reverse('organizations'))

    c['form'] = form
    c['instance'] = instance

    return render_to_response('cat/edit_organization.html', c, context_instance=RequestContext(request))
4

1 に答える 1

0

Organization.save() 内で self.save() を呼び出しているため、再帰エラーが発生しています。save() をオーバーライドしながら保存したい場合は、独自の save() の代わりにスーパークラスのバージョンの save() を呼び出してください。

インスタンスを m2m リレーションシップに追加する前に、リレーションシップの両側にすでにプライマリ キーが必要です (つまり、データベースに挿入済み)。つまり、保存も作成もされていないオブジェクトを m2m 関係に追加することはできません。

これを行う:

organisation.save()
user.save()
organisation.administrators.add(user)

モデルの save メソッドがユーザーのモデルも保存した場合はまったく予想外であるため、ビューまたはフォーム内でこれを行うことをお勧めします (ただし、モデルの save() 内でも機能するはずです)。

于 2014-01-11T20:23:28.687 に答える