KeyError, в то время как CreateView с двумя отношениями ForeignKey - PullRequest
0 голосов
/ 17 октября 2019

Модели

Я создал две модели в приложении Журналы. Одна модель предназначена для журнала (to_journal), а другая - для записей журнала (to_journal_entry). Модель to_journal связана с моделью пользователя через «пользователь журнала», а модель to_journal_entry связана с to_journal через journal_name.

. Она выглядит примерно так:

enter image description here

models.py

class to_journal(models.Model):
    journal_name = models.CharField(max_length = 40)
    slug = AutoSlugField(populate_from='journal_name')
    date_created = models.DateTimeField(auto_now_add=True)
    journal_user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,)

    def __str__(self):
        return str(self.journal_user) + " " + self.name

    def get_absolute_url(self):
        return reverse('to-journals')


class to_journal_entry(models.Model):
    body = models.TextField()
    entry_date = models.DateTimeField(auto_now_add=True)
    journal_name = models.ForeignKey(to_journal, on_delete=models.CASCADE,)
    journal_user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,)

    def __str__(self):
        return str(self.journal_name) + " " + str(self.entry_date)

    def get_absolute_url(self):
         return reverse('to_journals', args=[str(self.slug)])

Просмотры

Я успешно настроил CreateView для to_journal. На соответствующей странице я ввожу название журнала, который я хочу дать своему журналу, нажимаю кнопку «Добавить» и страница обновляется, отображая обновленный список журналов. Это достигается с помощью CreateToJournal представления ниже.

enter image description here

Я хочу добиться того же самого для записей в журнале. Как только я нахожусь «внутри» любого данного журнала, я хочу иметь возможность вводить текст, и я хочу, чтобы страница перезагрузилась и обновила список записей только для этого конкретного журнала.

enter image description here

Ошибка

Когда я нажимаю кнопку добавления здесь, я получаю ошибку:

enter image description here

Для этой строки:

enter image description here

Я столкнулся с проблемами на этом шаге. Когда я пишу свой form_valid:

def form_valid(self, form):
        current_journal_id = to_journal.objects.get(id=self.kwargs['id'])
        form.instance.journal_user = self.request.user
        form.instance.journal_name = current_journal_id.journal_name
        return super(ToJournalEntriesList, self).form_valid(form)

, я указываю пользователя, говоря form.instance.journal_user = self.request.user, а текущий журнал - form.instance.journal_name = to_journal.objects.get(id=self.kwargs['id']).journal_name или что-то подобное (ниже приведен список других вещей, которые я пробовал).

views.py

class CreateToJournal(LoginRequiredMixin, CreateView):
    model = to_journal
    template_name = 'to_journals/to_journal_list.html'
    fields = ('journal_name',)

    def form_valid(self, form):
        form.instance.journal_user = self.request.user
        return super(CreateToJournal, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(CreateToJournal, self).get_context_data(**kwargs)
        context['to_journals'] = to_journal.objects.filter(journal_user=self.request.user)
        return context


class ToJournalEntriesList(LoginRequiredMixin, CreateView):
    model = to_journal_entry
    template_name = 'to_journals/to_journal_entries_list.html'
    fields = ('body',)
    success_url = reverse_lazy('to-journal-entries')

def form_valid(self, form):
    # line below should get the current object (Parent Journal)
    current_journal_id = to_journal.objects.get(id=self.kwargs['id'])

    form.instance.journal_user = self.request.user

    # Line below should set the journal name for the form as the journal name of the object I got earlier.
    form.instance.journal_name = current_journal_id.journal_name
    return super(ToJournalEntriesList, self).form_valid(form)

def get_context_data(self, **kwargs):
    context = super(ToJournalEntriesList, self).get_context_data(**kwargs)
    context['to_journal_entries'] = to_journal.objects.filter(journal_user=self.request.user)
    context['to_journal_entries'] = to_journal_entry.objects.filter(pk=self.kwargs.get('pk'))
    return context

Я пытался

  • form.instance.journal_name = to_journal. objects.get (id = self.kwargs.get ('id'))
  • form.instance.journal_name = to_journal.objects.get (pk = self.kwargs.get ('pk')) *
  • get_object_or_404 (to_journal, id = self.kwargs.get ('id'))
  • get_object_or_404 (to_journal, pk = self.kwargs.get ('pk'))
  • form.instance.journal_name = to_journal.objects.get (journal_name = self.kwargs.get ('journal_name')) *

Это дает мне ошибку DoesNotExist, что странно, так как янаходится в журнале, он должен автоматически забрать.

База данных

Просто хотел также показать базу данных, с которой я работаю. Он имеет столбец id, поэтому гипотетически должен работать нормально:

enter image description here

Шаблон

<h1 class="green-button" onclick="inputJournal(); this.onclick=null;">Add Entry</h1>
  <div id="new-journal">
     <form class="" id="myForm" action="" method="post">
       {% csrf_token %}
       {{ form }}
       <button type="submit" id="add-button">Add</button>
     </form>
  </div>

Извините за долгоПочта! Если потребуется какая-либо дополнительная информация, я буду рад предоставить больше. Я действительно ценю, что вы все смотрите.

Best, Расул

Редактировать

URL

to_journals / urls.py

from django.urls import path
from .views import CreateToJournal, ToJournalEntriesList


urlpatterns = [
    path('', CreateToJournal.as_view(), name='to-journals'),
    path('<slug:slug>', ToJournalEntriesList.as_view(), name='to-journal-entries'),
]

root urls.py

urlpatterns = [
    path('admin/', admin.site.urls),

    path('users/', include('users.urls')),
    path('users/', include('django.contrib.auth.urls')),

    path('', include('pages.urls')),

    path('to-journals/', include('to_journals.urls')),

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Редактировать 2

После предложенного ответа это новая ошибка.

enter image description here

enter image description here

Редактировать 3 - исправление (Спасибо, Дэниэл Роузман)

def form_valid(self, form):
        current_journal = to_journal.objects.get(journal_user=self.request.user, slug=self.kwargs['slug'])
        form.instance.journal_user = self.request.user
        form.instance.journal_name = current_journal
        return super(ToJournalEntriesList, self).form_valid(form)

Изменение заключается в вызове kwargs (slug вместо id) и в соглашении об именах current_journal вместо current_journal_id

1 Ответ

1 голос
/ 17 октября 2019

self.kwargs содержит именованные параметры, которые были переданы в URL для этого представления. Как мы видим из шаблонов, единственный kwarg, который передается в URL, это slug, который явно ссылается на поле slug журнала;в случае скриншота sleep. Вот что нам нужно использовать в методе, как для значения, так и для поля, чтобы найти его:

current_journal_id = to_journal.objects.get(slug=self.kwargs['slug'])

Но, пожалуйста, дайте вашим объектам имена, отражающие их на самом деле. Выше мы получаем фактический журнал, а не идентификатор;назовите это current_journal. Точно так же внешний ключ от записи указывает на журнал, а не на имя журнала;вам следует назвать FK to_journal (хотя я также не понимаю, почему ваша модель называется именно так, а не просто Journal).

Редактировать

Ваша вторая проблема напрямую связана с вашим заблуждением об именах. Это должно быть:

form.instance.journal_name = current_journal_id

(не current_journal_id.journal_name). Если бы вы назвали вещи правильно, это было бы

form.instance.journal = current_journal

, что было бы намного яснее и менее подвержено ошибкам.

...