Django inlineformset сохранить новый родитель и потомок - PullRequest
0 голосов
/ 29 мая 2019

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

models.py

from django.db import models

class MetaData(models.Model):
    description = models.CharField(max_length=5000)

class Image(models.Model):
    image = models.ImageField()
    metadata_id = models.ForeignKey(
        MetaData, on_delete=models.DO_NOTHING, related_name='image_to_metadata'
    )

С помощью моделей были созданы простые формы:

forms.py

from django.forms import ModelForm
from django.forms.models import inlineformset_factory
from .models import MetaData, Image

class MetaDataForm(ModelForm):
    class Meta:
        model = MetaData
        fields = '__all__'

class ImageForm(ModelForm):
    class Meta:
        model = Image
        fields = ('image',)

MetaDataImageFormSet = inlineformset_factory(MetaData, Image, fields=('image',), extra=1)

с последующим использованием следующего представления для их отображения и аутентификации на основе следующего руководства Встроенные наборы форм Django с представлениями на основе классов

представления.py

from django.views.generic import CreateView
from django.db import transaction

from .forms import MetaDataForm, MetaDataImageFormSet
from .models import MetaData

class CaptureView(CreateView):
    model = MetaData
    template_name = 'pages/capture.html'
    form_class = MetaDataForm
    success_url = '/'

    def get_context_data(self, **kwargs):
        data = super(CaptureView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['images'] = MetaDataFormSet(self.request.POST)
        else:
            data['images'] = MetaDataFormSet()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        images = context['images']
        with transaction.atomic():
            self.object = form.save()
            if images.is_valid():
                images.instance = self.object
                images.save()
        return super(CaptureView, self).form_valid(form)

urls.py

from django.urls import path

urlpatterns = [
    path("", CaptureView.as_view(), name="capture"),
]
#  Hiding django toolbar paths and error page handling

Когда я пытаюсь опубликовать изображение, я получаю следующее сообщение об ошибке

Файл "C: \ Users\ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ backends \ utils.py "в _execute 85. return self.cursor.execute (sql, params)

Вышеуказанное исключение (пустое значение в столбце«id» нарушает ограничение not-null. ПОДРОБНОЕ ОПИСАНИЕ. Недопустимая строка содержит (null, test1).) была прямой причиной следующего исключения:

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-пакеты \ django \ core \ handlers \ exception.py "во внутреннем 34. response = get_response (запрос)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ core \ handlers \ base.py" в _get_response 126. response = self.process_exception_by_middleware (e, request)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ core \ handlers \ base.py" в _get_response 124. response = wrapped_callback (запрос, * callback_args, ** callback_kwargs)

Файл "C: \ Users \ dbutler \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ contextlib.py" во внутренней 74. return func (* args, ** kwds)

File "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ views \ generic \ base.py "в представлении 68. вернуть self.dispatch (запрос, * аргументы, ** kwargs)

файл«C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ views \ generic \ base.py» в диспетчере 88. обработчик возврата (request, * args, ** kwargs)

File "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ views \ generic \ edit.py "в посте 172. return super (). Post (запрос, * аргументы, ** kwargs)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ views \ generic \ edit.py" в записи 142. return self.form_valid (форма)

Файл "C: \ code\ capture_version_2 \ recets \ views.py "в form_valid 27. self.object = form.save ()

Файл" C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ forms \ models ".py "в save 458. self.instance.save ()

Файл" C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ models \ base.py "в save 718. force_update = force_update, update_fields = update_fields)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ models \ base.py" в save_base 748. updated = self._save_table (raw, cls, force_insert, force_update, using, update_fields)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ models \ base.py" в _save_table 831. result = self._do_insert (cls._base_manager, using, fields, update_pk, raw)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ models \ base.py "в _do_insert 869. using = using, raw = raw)

Файл" C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ models\ manager.py "в manager_method 82. вернуть getattr (self.get_queryset (), name) (* args, ** kwargs)

Файл" C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages\ django \ db \ models \ query.py "в _insert 1136. вернуть query.get_compiler (using = using) .execute_sql (return_id)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ models \ sql \ compiler.py" в execute_sql 1289. cursor.execute (sql, params)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ debug_toolbar \ Panel \ sql \ tracking.py" в файле execute 186. возвращает self._record (self.cursor.execute, sql, params)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ debug_toolbar \ Panel \ sql \ tracking.py" в _record 124. метод возврата (sql, params)

Файл "C:\ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ backends \ utils.py "в execute 100. вернуть super (). Execute (sql, params)

Файл" C: \ Users\ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ backends \ utils.py "in execute 68. вернуть self._execute_with_wrappers (sql, params, many = False, executor = self._execute)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ backends \ utils.py" в _execute_with_wrappers 77. вернуть исполнителя (sql, params, many, context)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ backends \ utils.py" в _execute 85. вернуть self.cursor.execute (sql, params)

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ utils.py" в exit 89. повышение dj_exc_value.with_traceback (traceback) из exc_value

Файл "C: \ Users \ dbutler \ capture_version_2 \ lib \ site-packages \ django \ db \ backends \ utils.py" в _execute 85. вернуть self.cursor.execute (sql, params)

Тип исключения: IntegrityError at / Exception Value: нулевое значение в столбце "id" нарушает ненулевое ограничение. ПОДРОБНЕЕ: В ошибочной строке содержится (null, test1).

...