где проверить условия в универсальном UpdateView в Django

Я использую Django 2.0

У меня есть модель Note, и я использую общий вид обновления для обновления объекта заметки.

Конфигурация URL похожа на

app_name = 'notes'
urlpatterns = [
    path('<int:pk>/', NoteUpdate.as_view(), name='update'),
]

который доступен через настройку пространства имен в app.urls

/notes/<pk>

Я хочу выполнить некоторую проверку состояния в представлении перед загрузкой представления или сохранением обновленного значения.

Так как заметкой можно поделиться с любым пользователем, и существует единый шаблон для просмотра и обновления заметки. Я хочу проверить, является ли пользователь владельцем заметки или была ли заметка предоставлена ​​пользователю и предоставлено ли разрешение на запись.

class NoteUpdate(UpdateView):
    template_name = 'notes/new_note.html'
    model = Note
    fields = ['title', 'content', 'tags']

    def get_context_data(self, **kwargs):
        context = super(NoteUpdate, self).get_context_data(**kwargs)

        """
        check if note is shared or is owned by user
        """
        note = Note.objects.get(pk=kwargs['pk'])
        if note and note.user is self.request.user:
            shared = False
        else:
            shared_note = Shared.objects.filter(user=self.request.user, note=note).first()

            if shared_note is not None:
                shared = True
            else:
                raise Http404

        context['note_shared'] = shared_note
        context['shared'] = shared

        return context

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(self.__class__, self).dispatch(request, *args, **kwargs)

Это то, что я пробовал в get_context_data(), но оно дает KeyError при pk=kwargs['pk']

Кроме того, get_context_data() – это лучшее место для проверки условий или get_query()?


person Anuj TBE    schedule 22.12.2017    source источник


Ответы (1)


вам не нужно получать pk от kwargs, потому что ваша заметка уже существует как self.object, поэтому ваш код будет

class NoteUpdate(UpdateView):
    template_name = 'notes/new_note.html'
    model = Note
    fields = ['title', 'content', 'tags']

    def get_context_data(self, **kwargs):
        context = super(NoteUpdate, self).get_context_data(**kwargs)

        """
        check if note is shared or is owned by user
        """
        note = self.object
        if note and note.user is self.request.user:
            shared = False
        else:
            shared_note = Shared.objects.filter(user=self.request.user, note=note).first()

            if shared_note is not None:
                shared = True
            else:
                raise Http404

        context['note_shared'] = shared_note
        context['shared'] = shared

        return context

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(self.__class__, self).dispatch(request, *args, **kwargs)

Согласно этому хорошему ответу где использовать get_query_set и get_context_data:

get_query_set()

Используется ListViews — определяет список объектов, которые вы хотите отобразить. По умолчанию он просто даст вам все для указанной вами модели. Переопределяя этот метод, вы можете расширить или полностью заменить эту логику. Документация Django по этому вопросу.

class FilteredAuthorView(ListView):
    template_name = 'authors.html'
    model = Author

    def get_queryset(self):
        # original qs
        qs = super().get_queryset() 
        # filter by a variable captured from url, for example
        return qs.filter(name__startswith=self.kwargs.name)

get_context_data()

Этот метод используется для заполнения словаря для использования в качестве контекста шаблона. Например, ListViews заполнит результат get_queryset() как author_list в приведенном выше примере. Вероятно, вы будете чаще всего переопределять этот метод, чтобы добавлять элементы для отображения в ваших шаблонах.

def get_context_data(self, **kwargs):
    data = super().get_context_data(**kwargs)
    data['page_title'] = 'Authors'
    return data

И затем в своем шаблоне вы можете ссылаться на эти переменные.

<h1>{{ page_title }}</h1>

<ul>
{% for author in author_list %}
    <li>{{ author.name }}</li>
{% endfor %}
</ul>
person Bakhrom Rakhmonov    schedule 22.12.2017