Почему я не могу записать запись данных без внешнего ключа с моделью, которая содержит внешний ключ, допускающий значение NULL? - PullRequest
1 голос
/ 21 июня 2019

Я ознакомился с документацией django, в которой говорится, что если вам нужен внешний ключ, который может быть необязательным, вам необходимо задать следующие параметры для модели: on_delete = models.SET_NULL, blank = True, null = True, default = None

Я удалил всю базу данных, проверил поле в MYSql admin.Правильно установлено, что поле содержит значения NULL.Кто-нибудь может объяснить, почему это происходит или что я делаю не так?

Модель:

Model:
class MediaImage(models.Model):
    class Meta:
        verbose_name = _("Image")
        verbose_name_plural = _('Image')
    date_created = models.DateTimeField(auto_now_add=True)
    date_changed = models.DateTimeField(auto_now=True, auto_now_add=False)
    content = models.FileField(upload_to=person_directory_path, storage=private_storage, verbose_name=_("Image"))
    title = models.CharField(max_length=50, verbose_name=_("Titel"), blank=True)
    classification = models.CharField(max_length=10, default="image")
    person = models.ForeignKey(Person, on_delete=models.SET_NULL, blank=True, null=True, default=None)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_("User"))

Вид:

@login_required
def mediafiles_add_image(request):
  if request.method == "POST":
      form = MediafilesAddImage(request.user, request.POST, request.FILES)
      if form.is_valid():
          image_file = request.FILES['content']
          if request.POST['person_id']:
            ImageFile = MediaImage(content=image_file, person_id=request.POST['person_id'], title=request.POST['title'], user_id=request.user)
          else:
            ImageFile = MediaImage(content=image_file, title=request.POST['title'], user_id=request.user)
          ImageFile.save()
          return redirect('mediafiles')
  else:
    form = MediafilesAddImage(request.user)    
    return render(request, 'mediafiles/mediafiles_add_image.html', {'form': form})
  return HttpResponseForbidden('Something went wrong.')

Форма:

class MediafilesAddImage(forms.ModelForm):
  class Meta:
    model = MediaImage
    fields = ('person_id', 'title', 'content')
  #person_id = forms.ChoiceField(label=_('Relation'))
  #content = forms.FileField(label=_('Image'), widget=forms.FileInput(attrs={'accept':'image/*'}))
  #title = forms.CharField(max_length=50, required=False)

  def __init__(self, user, *args, **kwargs):
    super(MediafilesAddImage, self).__init__(*args, **kwargs)
    self.fields['person_id'].queryset = Person.objects.filter(user_id=user)
    self.fields['person_id'].required = False

Ошибка возникает в строке:

ImageFile.save()

Запись должна обычно сохраняться здесь, но я получаю ошибку: AttributeError в / admin / datawarehouse / mediaimage / add / объект 'NoneType' не имеет атрибута 'id'

Полная трассировка ошибок:

Environment:


Request Method: POST
Request URL: http://localhost:8000/mediafiles/add/image

Django Version: 2.1.7
Python Version: 3.7.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'users.apps.UsersConfig',
 'pages.apps.PagesConfig',
 'bootstrap4',
 'crispy_forms',
 'debug_toolbar',
 'rest_framework',
 'phonenumber_field',
 'dashboard',
 'datawarehouse',
 'students',
 'appointment',
 'mediafiles',
 'bootstrap_datepicker_plus']
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',
 'debug_toolbar.middleware.DebugToolbarMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'user_language_middleware.UserLanguageMiddleware']



Traceback:

File "C:\Program Files\Python37\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Program Files\Python37\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "C:\Program Files\Python37\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Program Files\Python37\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)

File "C:\Users\Administrator\Documents\Django\vierklang\klangkuppler\mediafiles\views.py" in mediafiles_add_image
  56.           ImageFile.save()

File "C:\Program Files\Python37\lib\site-packages\django\db\models\base.py" in save
  718.                        force_update=force_update, update_fields=update_fields)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\base.py" in save_base
  748.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\base.py" in _save_table
  831.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\base.py" in _do_insert
  869.                                using=using, raw=raw)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\query.py" in _insert
  1136.         return query.get_compiler(using=using).execute_sql(return_id)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
  1288.             for sql, params in self.as_sql():

File "C:\Program Files\Python37\lib\site-packages\django\db\models\sql\compiler.py" in as_sql
  1241.                 for obj in self.query.objs

File "C:\Program Files\Python37\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
  1241.                 for obj in self.query.objs

File "C:\Program Files\Python37\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
  1240.                 [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]

File "C:\Program Files\Python37\lib\site-packages\django\db\models\sql\compiler.py" in pre_save_val
  1192.         return field.pre_save(obj, add=True)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\fields\files.py" in pre_save
  288.             file.save(file.name, file.file, save=False)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\fields\files.py" in save
  86.         name = self.field.generate_filename(self.instance, name)

File "C:\Program Files\Python37\lib\site-packages\django\db\models\fields\files.py" in generate_filename
  303.             filename = self.upload_to(instance, filename)

File "C:\Users\Administrator\Documents\Django\vierklang\klangkuppler\datawarehouse\models.py" in person_directory_path
  40.     return 'person_{0}/{1}/{2}'.format(instance.person_id.id, date, filename)

Exception Type: AttributeError at /mediafiles/add/image
Exception Value: 'NoneType' object has no attribute 'id'

1 Ответ

0 голосов
/ 21 июня 2019

Вы пытаетесь получить доступ к id из типа None, поэтому выдается ошибка. Итак, Вы можете изменить

return 'person_{0}/{1}/{2}'.format(instance.person_id.id, date, filename)

до

if instance.person_id:
    return 'person_{0}/{1}/{2}'.format(instance.person_id.id, date, filename)
else:
    return 'person_{0}/{1}/{2}'.format('None', date, filename)

Это должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...