Как удалить экземпляр поля ManyToMany? - PullRequest
0 голосов
/ 18 марта 2019

У меня есть две модели:

class Organisation(models.Model):
    user        = models.OneToOneField(settings.AUTH_USER_MODEL,related_name='organisation_user',on_delete=models.CASCADE)
    name        = models.CharField(max_length=100,blank=True)
    location    = models.CharField(max_length=100,blank=True)
    qualification_status = (
        ('Pending for verification','Pending for verification'),
        ('Verified','Verified'),
        )
    qualification   = models.CharField(max_length=100,choices=qualification_status,default='Pending for verification',blank=True)
    members         = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='organisation_members',blank=True)

class Organisation_member(models.Model):
    user            = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
    organisation    = models.ForeignKey(Organisation,on_delete=models.CASCADE,related_name='organisation_staff')
    member_name     = models.ForeignKey(settings.AUTH_USER_MODEL,related_name='organisation_staff_member',on_delete=models.CASCADE,null=True,blank=True)
    is_admin        = models.BooleanField(default=False)

У меня есть этот сигнал для создания Organisation_member модели:

@receiver(post_save, sender=Organisation)
def organisation_admin(sender, instance, created, **kwargs):
    for member in instance.members.all():
        if Organisation_member.objects.filter(user=instance.user,organisation=Organisation.objects.filter(user=instance.user,name=instance.name).first(),member_name=member).exists():
            pass
        else:
            Organisation_member.objects.update_or_create(User=instance.User,organisation=Organisation.objects.filter(user=instance.user,name=instance.name).first(),member_name=member,is_admin=False)

Сигнал указывает на то, что когда я добавляю элемент в свое поле много, он автоматически создает объект Organisation_member из выбранного элемента.

Сигнал работает отлично.

Моя проблема в обратном, т. Е. Когда я пытаюсь удалить объект Organisation_member, он также должен удалить член из множества отношений родительской модели.

Я пробовал это:

@login_required()
def delete_members(request, pk):
    user_organisation = get_object_or_404(Organisation, user=request.user)
    member_to_delete = Organisation_member.objects.filter(pk=pk)
    if member_to_delete.exists():
        member_to_delete[0].delete()
        for member in user_organisation.members.all():
            user_organisation.members.remove(member=member_to_delete[0])
    return redirect(reverse('userprofile:organisation_member_list'))

Но он не удаляет член из родительской модели ..

Любой, кто знает решение, пожалуйста, помогите.

Спасибо

Ответы [ 2 ]

1 голос
/ 18 марта 2019

Попробуйте что-то вроде этого:

@login_required()
def delete_members(request, pk):
    user_organisation = get_object_or_404(Organisation, user=request.user)
    member_to_delete = get_object_or_404(Organisation_member, pk=pk)
    user_organisation.members.remove(member_to_delete.member_name)
    member_to_delete.delete()
    return redirect(reverse('userprofile:organisation_member_list'))

См. Официальный документ Django

0 голосов
/ 18 марта 2019

Стандартным способом использования такого рода отношений будет указание Organisation_member в качестве модели through для members в Organisation.Тогда база данных позаботится об этом для вас без каких-либо сигналов.

class Organisation(models.Model):
    members = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        through='Organisation_member')

Единственная проблема в том, что у вас есть две ссылки на User в Organisation_member: member_name и user.Зачем?Вам, вероятно, нужен только один, и вы должны удалить другой.Если есть причина для двух разных пользователей в Organisation_member, вам необходимо указать поля, которые будут использоваться для отношения:

    members = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        through='Organisation_member',
        through_fields=('organisation', 'member_name'))

Вот и все, Organisation_member s автоматически добавляются и удаляются всякий раз, когда выдобавить или удалить пользователя для members.

...