Django 2.1.1, IntegrityError, ограничение NOT NULL не выполнено :apers_paper.seminary_id - PullRequest
0 голосов
/ 09 сентября 2018

Python версия: 3.7 Джанго версия 2.1.1

Я новичок в django, и я учу себя в основном с помощью учебных пособий и «проб и ошибок». Я искал stackoverflow, но ни один из предыдущих вопросов не подходит к моей проблеме. Например, они ссылаются на пустые поля CharFields, и я не думаю, что это моя проблема здесь.

Я думал, что связал два класса Семинария и Бумага через ForeignKey. Прямо сейчас я могу добавить Seminary в базу данных через соответствующую форму и отобразить ее так, как я хочу. Но со второй формой, рассматривающей класс Paper , django выдает мне ошибку:

Способ запроса: POST

Тип исключения: IntegrityError

Значение исключения: ограничение NOT NULL не выполнено :apers_paper.seminary_id

документы это мое приложение, кстати

Вот модели.py, без мета:

class Seminary(models.Model):
slug = models.SlugField(unique=True)
seminary_type = models.CharField(max_length=25, choices=choices.SEMINARY_TYPE_CHOICES)
seminary_title = models.CharField(max_length=200)
seminary_year = models.IntegerField(choices=choices.YEAR_CHOICES, default=datetime.now().year)
summer_winter = models.CharField(max_length=6, choices=choices.SEASON_CHOICES, default="S")

def get_absolute_url(self):
    return reverse('papers:paper-detail', kwargs={'slug': self.slug})

def __str__(self):
    return self.seminary_title


def create_slug(instance, new_slug=None):
    slug = slugify(instance.seminary_title)
    if new_slug is not None:
        slug = new_slug
    qs = Seminary.objects.filter(slug=slug)
    exists = qs.exists()
    if exists:
        new_slug = "%s-%s" % (slug, qs.first().pk)
        return create_slug(instance, new_slug=new_slug)
    return slug


def pre_save_post_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = create_slug(instance)


pre_save.connect(pre_save_post_receiver, sender=Seminary)


class Paper(models.Model):
    seminary = models.ForeignKey(Seminary, on_delete=models.CASCADE, primary_key=True)
    paper_title = models.CharField(max_length=200, blank=False, help_text="Please enter the title ")
    author = models.CharField(max_length=50, blank=True)
    upload_paper = ContentTypeRestrictedFileField(
        upload_to='papers/pdf',
        content_types=['application/pdf'],
        max_upload_size=5242880,
        blank=True
    )

    def get_absolute_url(self):
        return reverse('papers:paper-index', kwargs={'slug': self.slug})

Вот views.py:

class IndexView(generic.ListView):
    template_name = 'papers/index.html'
    context_object_name = 'all_papers'

    def get_queryset(self):
        return Seminary.objects.all()


class DetailView(generic.DetailView):
    model = Seminary
    template_name = 'papers/detail.html'


class SeminaryCreate(CreateView):
    model = Seminary
    fields = ['summer_winter',
              'seminary_year',
              'seminary_type',
              'seminary_title',
              ]


class PaperCreate(CreateView):
    model = Paper
    fields = [
        'paper_title',
        'author',
        'upload_paper',
    ]

Я уверен, что я что-то путаю. Если мне нужно предоставить дополнительную информацию, пожалуйста, спросите, и я добавлю ее к своему вопросу. Заранее спасибо!

Edit:

Я добавил семинарию к представлению PaperCreate в соответствии с рекомендациями @bluegrounds Теперь вместо этого выдается следующая ошибка:

Тип исключения: неправильно настроен

Значение исключения: URL-адрес для перенаправления отсутствует. Либо укажите URL, либо определить метод get_absolute_url в модели.

Во всяком случае, выбор семинара не предполагается: несколько документов, каждый из которых выделен только на один конкретный семинар.

Завершить трассировку после изменения представления PaperCreate :

Request Method: POST
Request URL: http://127.0.0.1:8000/papers/seminartitel15/add/

Django Version: 2.1.1
Python Version: 3.7.0
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'transcript.apps.TranscriptConfig',
 'biblio.apps.BiblioConfig',
 'papers.apps.PapersConfig',
 'crispy_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/usr/lib/python3.7/site-packages/django/views/generic/edit.py" in get_success_url
  116.                 url = self.object.get_absolute_url()

File "/home/bjoern/MyCode/PycharmProjects/websiteTwo/websiteTwo/papers/models.py" in get_absolute_url
  68.         return reverse('papers:paper-index', kwargs={'slug': self.slug})

During handling of the above exception ('Paper' object has no attribute 'slug'), another exception occurred:

File "/usr/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/usr/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/usr/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/lib/python3.7/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/usr/lib/python3.7/site-packages/django/views/generic/base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "/usr/lib/python3.7/site-packages/django/views/generic/edit.py" in post
  172.         return super().post(request, *args, **kwargs)

File "/usr/lib/python3.7/site-packages/django/views/generic/edit.py" in post
  142.             return self.form_valid(form)

File "/usr/lib/python3.7/site-packages/django/views/generic/edit.py" in form_valid
  126.         return super().form_valid(form)

File "/usr/lib/python3.7/site-packages/django/views/generic/edit.py" in form_valid
  57.         return HttpResponseRedirect(self.get_success_url())

File "/usr/lib/python3.7/site-packages/django/views/generic/edit.py" in get_success_url
  119.                     "No URL to redirect to.  Either provide a url or define"

Exception Type: ImproperlyConfigured at /papers/seminartitel15/add/
Exception Value: No URL to redirect to.  Either provide a url or define a get_absolute_url method on the Model.

urls.py:

urlpatterns = [
    path('papers/new/', views.SeminaryCreate.as_view(), name='seminary-add'),
    path('papers/', views.IndexView.as_view(), name='paper-index'),
    path('papers/<str:slug>/', views.DetailView.as_view(), name='paper-detail'),
    path('papers/<str:slug>/add/', views.PaperCreate.as_view(), name='paper-add'),

]

Edit_2: Я не мог решить всю проблему, но совет @bluegrounds оказался полезным. Кроме того, я изменил get_absolute_url класса бумаги на

 def get_absolute_url(self):
        return reverse('papers:paper-detail', args=[str(self.seminary.slug)])

как указано в документации.

Теперь у меня проблемы с моим шаблоном, но я задам новый вопрос для этого. Пока большое спасибо!

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Я тоже не эксперт, но думаю, что это потому, что в вашем представлении PaperCreate нет способа связать объект Paper с объектом Seminary, как, например, ожидает база данных. Каждый объект Paper должен иметь идентификатор объекта Seminary, поскольку вы добавили его в класс модели Paper:

class Paper(models.Model):
    seminary = models.ForeignKey(Seminary, on_delete=models.CASCADE, primary_key=True)

и поскольку поле ForeignKey не может быть нулевым, оно вызывает NOT NULL constraint failed: papers_paper.seminary_id

Так что, возможно, сделайте это, посмотрите, работает ли оно:

class PaperCreate(CreateView):
    model = Paper
    fields = [
        'seminary',
        'paper_title',
        'author',
        'upload_paper',
    ]

Если я правильно помню, CreateView должен позаботиться об отображении выпадающего меню на веб-странице с доступными объектами семинарии.

Примечание

Вы уверены, что здесь указан атрибут первичного ключа?

class Paper(models.Model):
    seminary = models.ForeignKey(Seminary, on_delete=models.CASCADE, primary_key=True)
0 голосов
/ 09 сентября 2018

Не выполнено ограничение IntegrityError, NOT NULL :apers_paper.seminary_id.
Эта ошибка означает, что у вас есть внешний ключ для модели Seminary in Paper с ограничением не равным NULL, но при создании объекта Paper вы не передаете значение Seminary (Внешний ключ).

...