在保存到DJANGO中之前,从视图中检索ForeignKey

时间:2019-05-27 17:04:02

标签: django python-3.x django-forms django-views django-queryset

我该如何从表单子关系中检索外键,并在将父信息保存到同一页面的同时进行保存。

我目前正在使用两种形式,父母和孩子。该页面的逻辑是保存一本书的名称和其中包含的课程的名称。

Ex:本书=“学习数据结构和算法”,     语言=“ 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正在数据库中保存“ Book”的名称,而不是“ Language”的名称。系统也会中断并返回以下消息: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 个答案:

答案 0 :(得分:1)

您的诊断根本不正确。密码没有所有者字段,或者实际上与用户没有任何关系。它与Entity之间的关系是错误的,并且错误明确指出它是实体还是缺少实体。因此,您只需分配刚刚创建的实体:

    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的结果不是表单,而是模型的实例。