Обновление и удаление нескольких изображений с помощью Formset в Django

Я новичок в Django, поэтому прошу прощения за глупые ошибки в моем коде. Я сделал сообщение с несколькими изображениями, используя FBV. он отлично работает и выполняет свою работу по добавлению нескольких изображений в сообщение. Сейчас я работаю над редактированием сообщения, однако у меня возникли проблемы с редактированием сообщения, я получаю следующую ошибку.

AttributeError at /gangsters/edit/Scarface-the-story-of-Al-Capone/
'tuple' object has no attribute '_committed'
Request Method: POST
Request URL:    http://127.0.0.1:8000/gangsters/edit/Scarface-the-story-of-Al-Capone
Django Version: 1.11
Exception Type: AttributeError
Exception Value:    
'tuple' object has no attribute '_committed' 

Краткое описание моих моделей Допустим, я пытаюсь создать это веб-приложение, которое позволяет пользователям писать о гангстерах (больше похоже на пост-модель) со всего мира и из разных периодов времени. Есть 2 модели. Гангстеры и члены банд. У GangMember есть чужой ключ к Гангстеру

мои модели как ниже

class Gangster(models.Model):
    user = models.ForeignKey(User, related_name='posts')
    gangster_name = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(allow_unicode=True, unique=True)
    history = models.TextField()
    gangster_image = models.ImageField()
    # there are more attributes like "Post-like but ignoring them as they are not relevant here"

def save(self, *args, **kwargs):
    self.slug = slugify(self.title) #for SEO on google searches
    super().save(*args, **kwargs)

class Gangmember(models.Model): 
    gangster = models.ForeignKey(Gangster, on_delete=models.CASCADE, related_name = "ganglord")
    gangmember_image= models.ImageField(upload_to='images/', blank=True, null=True, default='')
    gangmember_name = models.CharField(max_length=100, default='')
    brief_description = models.CharField(max_length=1000, default='')

ниже мой gangster_edit views.py

@login_required
def gangster_edit(request, slug):
    gangster = get_object_or_404(Gangster, slug=slug)
    ImageFormSet = modelformset_factory(Gangmember, fields=('gangmember_image', 'gangmember_name', 'gangmember_description'), extra=7, max_num=7)
    if gangster.user != request.user:
        raise Http404()
    if request.method == "POST":
        form = GangsterEditForm(request.POST or None, request.FILES or None, instance=gangster)
        formset = ImageFormSet(request.POST or None, request.FILES or None)

        if form.is_valid() and formset.is_valid():
            form.save()
            print(formset.cleaned_data)
            data = GangMember.objects.filter(gangster=gangster)
            for index, f in enumerate(formset):
                if f.cleaned_data:
                    if f.cleaned_data['id'] is None:
                        photo = GangMember(gangster=gangster, image=f.cleaned_data.get('image'), image_title=f.cleaned_data.get('image_title'),
                                     image_description=f.cleaned_data.get('image_description'))
                        photo.save()
                    elif (f.cleaned_data['image'], f.cleaned_data['image_title'], f.cleaned_data['image_description']) is False:
                        photo = Gangmember.objects.get(id=request.POST.get('form-' + str(index) + '-id'))
                        photo.delete()
                    else:
                        photo = Gangmember(gangster=gangster, image=f.cleaned_data.get('gangmember_image'), image_title=f.cleaned_data.get('gangmember_name'),
                                     image_description=f.cleaned_data.get('gangmember_description'))
                        d = GangMember.objects.get(id=data[index].id)
                        d.gangmember_image=photo.gangmember_image,
                        d.gangmember_name=photo.gangmember_name,
                        d.gangmember_description=photo.gangmember_description
                        d.save()
            return HttpResponseRedirect(gangster.get_absolute_url())
    else:
        form = GangsterEditForm(instance=gangster)
        formset = ImageFormSet(queryset=Gangmember.objects.filter(gangster=gangster))
    context = {'form': form, 'gangster': gangster, 'formset': formset}
    return render(request, 'gangsters/gangster_edit.html', context)

Прошу прощения, если вопрос слишком длинный. Опять же, мое представление gangster_edit не работает и выдает ошибку AttributeError. Сведения об ошибке вставлены выше. Если вы дочитали до этого момента, большое спасибо за попытку помочь мне решить эту проблему.

Ошибка TraceBack

System check identified no issues (0 silenced).
May 02, 2018 - 22:22:03
Django version 1.11, using settings 'Khal.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.


[02/May/2018 22:22:46] "GET /gangsters/samir/al-capone-from-chicago/ HTTP/1.1" 200 31213
[02/May/2018 22:22:49] "GET /gangsters/edit/al-capone-from-chicago/ HTTP/1.1" 200 18773
[{'gangmember_image': <ImageFieldFile: images/3.jpg>, 'gangmember_name': 'A', 'brief_description': 'This is A You will love A', 'id': <Gangmember: Al Capone from Chicago Image>}, {'gangmember_image': <InMemoryUploadedFile: B.jpg (image/jpeg)>, 'gangmember_name': 'B', 'brief_description': 'This is B
You will love B', 'id': None}, {'gangmember_image': <InMemoryUploadedFile: C.jpg (image/jpeg)>, 'gangmember_name': 'C', 'brief_description': 'Thi
s is C You will love C', 'id': None}, {'gangmember_image': <InMemoryUploadedFile: D.jpg (image/jpeg)>, 'gangmember_name': 'D', 'image_description
': 'This is D You will love D', 'id': None}, {'gangmember_image': <InMemoryUploadedFile: E.jpg (image/jpeg)>, 'gangmember_name': 'E.', 'brief_description': 'This is E You will love E', 'id': None}, {}, {}]
Internal Server Error: /gangsters/edit/al-capone-from-chicago/
Traceback (most recent call last):
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Samir\Documents\gangsters\views.py", line 144, in gangster_edit
    d.save()
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py", line 806, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py", line 836, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py", line 900, in _save_table
    for f in non_pks]
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py", line 900, in <listcomp>
    for f in non_pks]
  File "C:\Users\Samir\Miniconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\fields\files.py", line 295, in pre_save
    if file and not file._committed:
AttributeError: 'tuple' object has no attribute '_committed'
[02/May/2018 22:23:28] "POST /gangsters/edit/Scarface-the-story-of-Al-Capone

/ HTTP / 1,1 "500 112934

Можете ли вы опубликовать полную трассировку? Это может дать еще несколько подсказок относительно того, где в коде возникает проблема.

Will Keeling 02.05.2018 14:19

@WillKeeling Большое спасибо за то, что вы изучили это, я добавил трассировку, я все еще изучаю Django, поэтому, пожалуйста, простите любые глупые ошибки

Samir Tendulkar 03.05.2018 04:44

Спасибо. Я думаю, что проблема, возможно, связана с тем, что Prep.gangmember_image не ссылается на изображение (ссылаясь на кортеж). Если бы вы также могли опубликовать код для Prep, я мог бы подтвердить это.

Will Keeling 03.05.2018 09:56

@WillKeeling Я изменил код в соответствии с вашим советом. Я считаю, что в приведенном ниже коде else может быть ошибка. Не могу понять, что хоть else: photo = Gangmember(gangster=gangster, image=f.cleaned_data.get('gangmember_image'), image_title=f.cleaned_data.get('gangmember_name'), image_description=f.cleaned_data.get('gangmember_description‌​')) d = ..... d.save()

Samir Tendulkar 04.05.2018 03:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
502
0

Другие вопросы по теме