Удалите отдельные экземпляры ManyToManyRelationship через представление Django - PullRequest
1 голос
/ 26 января 2020

Итак, у меня есть Assignment модель:

class Assignment(models.Model):
    has_applied = models.ManyToManyField('driver.Driver', blank=True, verbose_name=_(
        "Driver applications"), related_name="driver_applications")

, которая имеет поле has_applied с отношением ManyToMany к модели Driver. Я хочу, чтобы пользователь переднего плана мог удалить эти отношения.

У меня есть обычный DetailView из модели Assignment, и я использую его для отображения списка кандидатов для Assignment экземпляра:

class AssignmentCandidateDetailView(generic.DetailView):
    model = Assignment
    context_object_name = 'assignment_candidate_detail'
    template_name = 'pages/candidate/c.html'

С этим URL:

path('assignment/<int:pk>/candidates', views.AssignmentCandidateDetailView.as_view(), name='assignment-candidate-detail'),

И в шаблоне я использую это, чтобы получить список кандидатов, которые подали заявки, и их информацию:

{% for entry in assignment_candidate_detail.has_applied.all %}
..... stuff
{% endfor %}

В шаблоне список кандидатов Я хотел бы добавить кнопку «Удалить» для каждого кандидата. Эта кнопка удалит отношение поля ManyToMany этого конкретного кандидата. Но я не уверен, как подойти к этому. Может кто-нибудь помочь?

Я полагаю, это должно быть что-то вроде (псевдокод):

def assignment_candidate_delete(request, pk):
    assignment = get_object_or_404(Assignment, pk=pk)
    assignment.has_applied.remove(candidate)

Но как я могу передать правильную информацию, чтобы она удаляла только отношения конкретного кандидата? ?

РЕДАКТИРОВАТЬ:

Итак, основываясь на ответе, я попробовал это:

URL:

path('assignment/<int:pk>/candidates/delete/<int:id>', views.assignment_candidate_delete, name='assignment-candidate-delete'),

Просмотров:

def assignment_candidate_delete(request, pk, id):
    assignment = get_object_or_404(Assignment, pk=pk)
    assignment.has_applied.remove(id)

Шаблон:

{% for entry in candidates %}
    <a href="{% url 'assignment-candidate-delete' request.resolver_match.kwargs.pk entry.id %}">Delete</a>
{% endfor %}

Для меня это кажется очень уродливым и хакерским способом получить pk текущей страницы. Есть ли другой способ получить нужный ПК?

1 Ответ

1 голос
/ 26 января 2020

Внутри тела вашего DELETE запроса у вас должно быть что-то вроде

{
    "candidate_id": "<<<<ID>>>"
}

и внутри вашего взгляда

def assignment_candidate_delete(request, pk, id):
    assignment = get_object_or_404(Assignment, pk=pk)
    candidate = get_object_or_404(Driver, pk=id)
    # Check for permissions if user is authorized to do such operation.
    assignment.has_applied.filter(has_applied_id=id).delete()
    # I am not sure if 'has_applied_id' is the correct field name for the driver's
    # id on the join table, if not just use the equivalent one. 

Обновление ответа:

для генерации URL шаблона

{% url 'assignment-candidate-delete' pk="<<<ASSIGNMENT_PK>>>>>" id="<<<<Driver ID>>>>" %}
# Just replace these with the respective data needed.
...