Django: Как мне получить доступ к pk строки таблицы, которая была отправлена ​​через ModelForm? - PullRequest
0 голосов
/ 03 августа 2020

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

Это очень простая задача, которую я хочу, чтобы эта страница выполняла, чтобы затем перейти к другим вещам; вот почему у меня нет стилей или чего-то еще.

У меня есть модель Note, позволяющая пользователю добавлять и изменять текстовые заметки о каком-либо проекте на сайте. Каждая строка в таблице Note связана со строкой в ​​таблице Project через ForeignKey. Модель Note имеет несколько полей, но пока я хочу отредактировать только текстовое поле. Я также хочу иметь возможность редактировать одну, две или несколько одновременно и отправлять их, а также - в будущем - добавлять кнопку для добавления новой формы для новой заметки.

Это моя форма

from django import forms
from .models import Note

class NoteForm(forms.ModelForm):
        
    class Meta:
        model = Note
        fields = ('note_text',) # Only want to edit this field
        labels = {'note_text': (''),} # Don't want the label to be displayed

Это мое мнение

from django.shortcuts import render
from .models import Note
from .forms import NoteForm


def editor(request, project_id):
    
    forms = []

    # I know this may not be a good choice for var names here
    for i in Note.objects.filter(project_id=project_id):
        
        if request.method == 'POST':
            form = NoteForm(request.POST, instance=i)
            forms.append(form)
            
            if form.is_valid():
                # I realized this is not necessary
                # because I'm not processing any more data before saving.
                note = form.save(commit=False)
                note.save()
                
        else:
            forms.append(NoteForm(instance=i))

    return render(request, 'NotesApp/editor.html', {'forms': forms})

Это мое HTML

<form method="POST" class="note-form">
    {% csrf_token %}
    {% for form in forms %}
        {{ form.as_p }}
    {% endfor %}
    <input type="submit" value="Submit">
</form>

Однако я понимаю, что когда я получаю данные из POST у меня нет возможности узнать, какой заметке соответствуют данные.

Я создал три заметки вручную в оболочке; они отображаются правильно. Тем не менее, когда я редактирую один и отправляю его, ничего не происходит; Я получаю те же предыдущие данные, которые были в их текстовых полях. Единственное, что отличает - и тоже очень неправильно - это когда я редактирую последний. Эти данные берутся и сохраняются, но они сохраняются в каждой отдельной строке. Другими словами, если я изменю текст последней заметки, например, на «Последняя заметка», тогда все тексты заметок станут «Последней заметкой».

EDIT

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

Мне указали на другое место Formsets, и, читая о них, я понял, что лучше справлюсь с модельным набором форм. Мой новый views.py содержит это

from django.shortcuts import render
from .models import Note
from django.forms.models import modelformset_factory


def editor(request, project_id):
    
    # Create a formset with an empty form if the project has no notes
    if len(Note.objects.filter(project_id=project_id)) == 0:
         NoteFormset = modelformset_factory(Note, exclude=(), extra=1,
                                            fields=('note_text',),
                                            labels= {'note_text': (''),})
    
    # If the project has at least one note,
    # populate the forms with the existing objects
    # and add no blank forms.
    else:
         NoteFormset = modelformset_factory(Note, exclude=(), extra=0,
                                            fields=('note_text',),
                                            labels= {'note_text': (''),})
         formset = NoteFormset(queryset=Note.objects.filter(project_id=project_id))

    if request.method == 'POST':
         formset = NoteFormset(request.POST)
        
         if formset.is_valid():
             formset.save()

    return render(request, 'CapEdit/editor.html', {'formset': formset})

Мой HTML это

<form method="POST" class="caption-form">
    {{ formset.management_data }}
    {% csrf_token %}
    {{ formset.as_p }}
    <input type="submit" value="Submit">
</form>

Я был бы признателен за некоторые комментарии или лучшее решение для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...