Django modelmultiplechoicefield освобождает все объекты, которые не были в запросе - PullRequest
1 голос
/ 26 июня 2011

Я чувствую, что моя проблема довольно очевидна и имеет тривиальное решение, но я не могу найти ее в течение нескольких часов ...

для реалистичного примера давайте представим, что у меня есть следующие модели:

class Report(models.Model):
    title = models.CharField(max_length=60)
    author = models.ForeignKey(User)
    posts = models.ManyToManyField(Post)

class Post(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(User)

Так что есть отчеты и посты. Сообщения могут быть связаны с некоторым отчетом. И есть следующая форма для привязки / освобождения сообщений к отчетам.

class AddPostsToReport(ModelForm):
    def __init__(self, user, *args, **kwargs):
        super(AddPostsToReport, self).__init__(*args, **kwargs)
        self.fields['posts'] = forms.ModelMultipleChoiceField(
             queryset=Post.objects.filter(author=user),
             required=False, 
             widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = Report
        fields = ('posts', )

Таким образом, я передаю дополнительный параметр (пользователь) в форму, и когда пользователь открывает страницу с этой формой, он может связывать / удалять только свои собственные сообщения.

Все отлично работает, кроме одного: когда пользователь сохраняет форму - все сообщения других пользователей, которые были связаны с этим отчетом, становятся несвязанными. Это не то, что мне нужно. Мне нужно, чтобы пользователь мог привязать / отменить привязку только своих сообщений к отчету, но сообщения других пользователей не изменяют его состояние.

Спасибо за любую помощь.

РЕДАКТИРОВАТЬ: вот представление (это не реальное представление, но логика реального представления точно такая же)

@login_required
def report_add_posts(request, report_id):
    report = get_object_or_404(Report, pk = report_id)

    if request.method == 'POST':
        form = AddPostsToReport(request.user, request.POST, instance = report)

        if form.is_valid():
            form.save()

            return HttpResponseRedirect(reverse(...))
    else:
        form = AddPostsToReport(request.user, instance = report)

    return render_to_response('report/page_with_form_to_add_posts.html', 
                              { 'form': form,
                                'report': report }, 
                              context_instance=RequestContext(request))

1 Ответ

1 голос
/ 26 июня 2011

Я не знаю "очень простого" способа решения вашей проблемы. Я бы использовал myform.save(commit=False) (из вида), и вместо вызова встроенного myform.save_m2m(), вызовите пользовательский метод AddPostsToReport.save_posts(), который проходит по self.instance['posts'], удаляя сообщения для указанного пользователя, а не в self.cleaned_data['posts'] и позже добавьте остальные новые сообщения.

...