Django - Как использовать функцию delete() в отношениях ManyToMany для удаления только одного отношения
У меня есть модель Voucher
, которая может быть распределена между несколькими users
.
Я использовал для этого отношения M2M
.
Я хочу, чтобы в шаблоне была возможность удалить ваучер, выделенный вошедшему пользователю, и только вошедшему пользователю (не все отношения).
Проблема у меня в том, что текущая модель удаляет всю модель для всех пользователей, вместо того, чтобы один пользователь запрашивал "delete".
Альтернативой, конечно, было бы просто создать модель Voucher
на ForeignKey, но что-то подсказывает, что я, вероятно, смогу сделать это с помощью M2M в представлениях.
Есть ли способ сфокусировать мою функцию удаления на конкретном пользователе? В приведенном ниже примере я пытался фильтровать на основе user.request
, что не работает. Если посмотреть на данные внутри модели, то в списке перечислены идентификаторы пользователей. Разве это не то, что делает request.user
?
модели
class Voucher(models.Model):
user = models.ManyToManyField(User, blank=True)
просмотров
def delete_voucher(request, voucher_id):
voucher = Voucher.objects.filter(pk=voucher_id).filter(user=request.user)
voucher.delete()
return redirect('account')
шаблон
<a class="button3 btn-block mybtn tx-tfm" href="{% url 'delete-voucher' voucher.id %}">Delete</a>
url
path('delete_voucher/<voucher_id>', views.delete_voucher, name='delete-voucher'),
Используйте метод .remove
. См. документацию M2M.
Со
def delete_voucher(request, voucher_id):
voucher = Voucher.objects.filter(pk=voucher_id).filter(user=request.user)
voucher.user.remove( request.user)
# note, more readable if the M2M field has a plural name voucher.users
return redirect('account')
Это симметрично, поэтому вы также можете сделать request.user.voucher_set.remove( voucher)
Возможно, вам будет полезно узнать, что существует промежуточная таблица, поддерживающая связь между объектом voucher
(строка в таблице ваучеров) и объектом user
. Каждая строка в этой таблице содержит внешний ключ к одному user
и внешний ключ к одному voucher
. .remove
удаляет строку в этой промежуточной таблице, оставляя объекты user
и voucher
неизменными.