Как я могу редактировать данные manytomanyfield

Я пытаюсь отредактировать данные многих полей. Вот моя модель

class Permission(models.Model):
    shop = models.ForeignKey(Shop, on_delete=models.SET_NULL, null=True)
    permission_title = models.CharField(max_length=255)

    class Meta:
        ordering = ["-id"]
    
    def __str__(self):
        return self.permission_title



class Roles(models.Model):
    shop = models.ForeignKey(Shop, on_delete=models.SET_NULL, null=True)
    role_title = models.CharField(max_length=255)
    permissions = models.ManyToManyField(Permission)

    class Meta:
        ordering = ["-id"]
    
    def __str__(self):
        return self.role_title

В этих моделях у меня есть модель под названием permission. Эта модель находится в отношении manytomanyfield с моделью Roles. Я хочу отредактировать это поле manytomanyfield. Я уже сделал часть создания. Но теперь я хочу отредактировать данные и показать их в шаблонах, которые я выбрал при создании роли. Я хочу отобразить входной тип checkox

Вот мое мнение:

def createRolesView(request, shop_id):
    shopId = get_object_or_404(Shop, pk=shop_id)
    permissions = Permission.objects.filter(
                shop=shopId.id
            )
    if shopId.user == request.user:
        if request.method == "POST":
            role_title = request.POST.get("role_title")
            shop = Shop.objects.get(id=shopId.id)
            permissions = request.POST.getlist("permissions")
            rl = Roles(
                role_title = role_title,
                shop = shop,
                
            )
            rl.save()
            for p in permissions:
                rl.permissions.add(p)

            rl.save()
            return redirect(f"/adminpanel/roles/{shopId.id}/")

        args = {
            "shopId": shopId,
            "permissions": permissions,
        }
        return render(request, "roles/create-role.html", args)
    else:
        return redirect("warning")


def editRolesView(request, role_id, shop_id):
    shopId = get_object_or_404(Shop, pk=shop_id)
    roleId = get_object_or_404(Roles, pk=role_id)

    if shopId.user == request.user:
        if request.method == "POST":
            roleId.role_title = request.POST.get("role_title")
            shop = Shop.objects.get(id=shopId.id)
            # roleId.permissions_set.all()
        args = {
            "shopId": shopId,
            "roleId": roleId,
        }
        return render(request, "roles/edit-role.html", args)
    else:
        return redirect("warning")

Только предложения, я не кодировал это сам.

Две простые таблицы

Один показывает текущие разрешения, назначенные роли, которая имеет кверисет roles.permissions.all(), вместе с флажком "удалить" для каждого.

Другой показывает доступные разрешения с флажком "добавить" для каждого. Кверисет может быть permissions.exclude( roles__pk=this_role.pk) (чтобы исключить уже добавленные, хотя добавлять что-то уже добавленное не вредно). Вы также должны исключить все разрешения, которые данному экземпляру роли не разрешено приобретать.

Вы можете использовать Django Formsets, но в этом случае также довольно просто обрабатывать необработанные данные из request.POST. Ваш шаблон будет представлять собой форму, содержащую экземпляры

<input type="checkbox" name="add" value="{{permission.pk}}" >

и

<input type="checkbox" name="remove" value="{{permission.pk}}" >

с соответствующим описательным текстом, собранным из экземпляра разрешения.

Если бы это был я, я бы отобразил их как таблицы слева и справа, но пока они находятся внутри <form> с кнопками Submit (и Done?), это не имеет значения.

При обработке POST вы получите проверенные значения pk с помощью request.POST.getlist('add') и request.POST.getlist('remove'). Для каждого из них проверьте, что он был в исходном наборе запросов, который был преобразован в форму, и если значения pk приемлемы

role.permissions.add( permission)  # or .remove( permission)

(где permission - экземпляр Permissions, который был перепроверен)

После выполнения вышеуказанных действий вы, вероятно, снова вернетесь к тому же самому, чтобы пользователь мог увидеть, что запрошенные добавления и удаления произошли. Кнопка "Готово" перенаправит в другое место( if "Done" in request.POST ... )

Вернуться на верх