首页 > 解决方案 > 通用 DeleteView 在 0x04725628 返回 django.db.models.query_utils.DeferredAttribute 对象 - Django

问题描述

免责声明:我只是一个尝试学习 Django 的新手

您好,我正在尝试重构我的代码并将我创建的所有视图修改为基于类的视图。我在使用 DeleteView 加载表单时遇到问题,该表单显示数据并同时被禁用。我取得了一些成功,唯一不知道该怎么做就是显示数据而不是现在出现的消息“<django.db.models.query_utils.DeferredAttribute object at 0x04725628>”

+模型.py:

class Note(models.Model):
title = models.CharField(max_length=30)
image_url = models.URLField()
content = models.TextField()
owner = models.ForeignKey(Profile, default=8, on_delete=models.CASCADE)

def get_absolute_url(self):
    return reverse(self.pk)

def __str__(self):
    return f'{self.title}'

+forms.py

class NoteForm(forms.ModelForm):
class Meta:
    model = Note
    exclude = ('owner',)


class DeleteNoteForm(NoteForm):
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    for (_, field) in self.fields.items():
        field.widget.attrs['readonly'] = True
        field.widget.attrs['disabled'] = True

+views.py

class DeleteNoteView(DeleteView):
model = Note
template_name = 'note-delete.html'
form_class = DeleteNoteForm
success_url = reverse_lazy('home page')

def get_context_data(self, **kwargs):
    data = super().get_context_data(**kwargs)
    data['form'] = self.form_class(instance=self.model)
    return data

+urls.py

path('delete/<int:pk>/', views.DeleteNoteView.as_view(), name='delete note'),

+模板

        <!--note delete data form-->
    <div class="form">
        <form method="POST">
            {{ form }}
            {% csrf_token %}
            <input type="submit" value="Delete"/>
        </form>
    </div>
    <!--end note delete data form-->

如果我使用我的视图,它工作正常,但我想修改它。

def delete_note(request, pk):
note = Note.objects.get(pk=pk)
if request.method=='GET':
    note_form = DeleteNoteForm(instance=note)
    context = {
        'note_form': note_form
    }
    return render(request, 'note-delete.html', context)
else:
    note.delete()
    return redirect('home page')

有人可以告诉我我错在哪里以及如何解决它,或者至少为我提供一个信息链接以了解为什么会发生这种情况?

标签: djangodjango-views

解决方案


您正在传递对模型类的引用DeleteNoteView,而您应该使用已删除的对象,因此:

class DeleteNoteView(DeleteView):
    model = Note
    template_name = 'note-delete.html'
    form_class = DeleteNoteForm
    success_url = reverse_lazy('home page')
    
    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)
        #       user self.object instead of self.model ↓
        data['form'] = self.form_class(instance=self.object)
        return data

我还建议过滤,以QuerySet使其他用户(不是a 所有者的用户无法Note删除它Note

from django.contrib.auth.mixins import LoginRequiredMixin

class DeleteNoteView(LoginRequiredMixin, DeleteView):
    model = Note
    template_name = 'note-delete.html'
    form_class = DeleteNoteForm
    success_url = reverse_lazy('home page')

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            owner=self.request.user
        )
    
    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)
        data['form'] = self.form_class(instance=self.object)
        return data

推荐阅读