Получить ForeignKey из просмотров перед сохранением в DJANGO - PullRequest
0 голосов
/ 27 мая 2019

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

В настоящее время я работаю с двумя формами, Родителеми ребенок.Логика страницы заключается в сохранении названия книги и названия курса, который она содержит.

Пример: Книга = "Изучить структуру данных и алгоритмы", Язык = "Python"

models.py

class Entity(models.Model):
    entity_name = models.CharField(max_length=250, blank=False)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='users')

    class Meta:
        verbose_name_plural = "Entities"

    def __str__(self):
        return self.entity_name

    def get_absolute_url(self):
        return reverse('snippets:password', kwargs={'pk': self.pk})


class Password(models.Model):
    password_name = models.CharField(max_length=12, blank=False)
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE, related_name='passwords')

    def __str__(self):
        return self.password_name

forms.py

from django import forms
from snippets.models import Entity, Password

class EntityForm(forms.ModelForm):
    class Meta:
        model = Entity
        fields = ('entity_name',)


class PasswordForm(forms.ModelForm):
    class Meta:
        model = Password
        fields = ('password_name',)

views.py

def password_creation(request):
    if request.method == 'POST':
        form_one = EntityForm(request.POST)
        form_two = PasswordForm(request.POST)
        if form_one.is_valid():
            entity_form = form_one.save(commit=False)
            entity_form.owner = request.user
            entity_form.save()
            password_form = form_two.save(commit=False)
            # HERE : what is the right way to retrieve name from PK
            # owner is not part the Password table field therefore
            # need to be changed to 'password_name'or 'entity'
            # then, how to retrieve the field from the view??
            password_form.owner = request.user
            password_form.save()
            return redirect('snippets:entity')

    else:
        form_one = EntityForm()
        form_two = PasswordForm() 


    context = {
        'form_one':form_one,
        'form_two':form_two,
    }

    return render(request, 'snippets/create-password.html', context)

Я пробовал коды выше.Проблема в том, что Django сохраняет имя «Книги», но не название «Языка» в базе данных.Система также ломается и возвращает это сообщение: NOT NULL constraint failed: snippets_password.entity_id.

Любая помощь будет принята с благодарностью.

Ошибка трассировки

Traceback (most recent call last):
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/password_change/snippets/views.py", line 67, in password_creation
    password_form.save()
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/base.py", line 729, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/base.py", line 759, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/base.py", line 842, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/base.py", line 880, in _do_insert
    using=using, raw=raw)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/query.py", line 1125, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1280, in execute_sql
    cursor.execute(sql, params)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/macadmin/Documents/Django_wapps/password_change_test/lib/python3.7/site-packages/django/db/backends/sqlite3/base.py", line 303, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: snippets_password.entity_id

1 Ответ

1 голос
/ 27 мая 2019

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

    if form_one.is_valid() and form_two.is_valid():
        entity = form_one.save(commit=False)
        entity.owner = request.user
        entity.save()
        password = form_two.save(commit=False)
        password.entity = entity
        password.save()

Обратите внимание, я добавил проверку того, что form_two является допустимым, а также переименовал объекты: результат вызова form.save - это не форма, а экземпляр модели.

...