モデルの管理者リストからユーザーが自滅するのを防ぐ必要があります。
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))