Пример демонстрации на основе classа Django

Кто-нибудь знает или может кому-нибудь создать простой пример универсального DeleteView на основе classа Django? Я хочу подclassифицировать DeleteView и убедиться, что пользователь, который в настоящий момент вошел в систему, имеет право собственности на объект до его удаления. Любая помощь будет очень высоко ценится. Заранее спасибо.

Вот простой:

from django.views.generic import DeleteView from django.http import Http404 class MyDeleteView(DeleteView): def get_object(self, queryset=None): """ Hook to ensure object is owned by request.user. """ obj = super(MyDeleteView, self).get_object() if not obj.owner == self.request.user: raise Http404 return obj 

Предостережения:

  • DeleteView не будет удалять запросы GET ; это ваша возможность предоставить шаблон подтверждения (вы можете указать имя в атрибуте classа template_name ) кнопкой «Да, я уверен», который POST s в этом представлении
  • Вы можете предпочесть сообщение об ошибке 404? В этом случае вместо этого delete метод delete , проверьте разрешения после вызова get_object и верните настроенный ответ.
  • Не забудьте success_url шаблон, который соответствует success_url classа success_url (необязательно настраиваемый), чтобы пользователь мог подтвердить, что объект был удален.

Я в основном подclassифицировал некоторые из Generic Class-Based-Views, чтобы сделать именно это. Основное различие заключается в том, что я просто отфильтровал запросы. Я не могу ручаться за то, является ли этот метод лучше или хуже, но для меня это имело больше смысла.

Не стесняйтесь игнорировать «MessageMixin» – это просто, чтобы легко представлять сообщения с помощью Django Messaging Framework с переменной, указанной для каждого представления. Вот код, который я написал для нашего сайта:

Просмотры

 from django.views.generic import CreateView, UpdateView, \ DeleteView, ListView, DetailView from myproject.core.views import MessageMixin class RequestCreateView(MessageMixin, CreateView): """ Sub-class of the CreateView to automatically pass the Request to the Form. """ success_message = "Created Successfully" def get_form_kwargs(self): """ Add the Request object to the Form's Keyword Arguments. """ kwargs = super(RequestCreateView, self).get_form_kwargs() kwargs.update({'request': self.request}) return kwargs class RequestUpdateView(MessageMixin, UpdateView): """ Sub-class the UpdateView to pass the request to the form and limit the queryset to the requesting user. """ success_message = "Updated Successfully" def get_form_kwargs(self): """ Add the Request object to the form's keyword arguments. """ kwargs = super(RequestUpdateView, self).get_form_kwargs() kwargs.update({'request': self.request}) return kwargs def get_queryset(self): """ Limit a User to only modifying their own data. """ qs = super(RequestUpdateView, self).get_queryset() return qs.filter(owner=self.request.user) class RequestDeleteView(MessageMixin, DeleteView): """ Sub-class the DeleteView to restrict a User from deleting other user's data. """ success_message = "Deleted Successfully" def get_queryset(self): qs = super(RequestDeleteView, self).get_queryset() return qs.filter(owner=self.request.user) 

Применение

Затем вы можете легко создавать свои собственные представления для использования этого типа функций. Например, я просто создаю их в своем urls.py:

 from myproject.utils.views import RequestDeleteView #... url(r'^delete-photo/(?P[\w]+)/$', RequestDeleteView.as_view( model=Photo, success_url='/site/media/photos', template_name='site/media-photos-delete.html', success_message='Your Photo has been deleted successfully.' ), name='fireflie-delete-photo-form'), 

формы

Важно отметить: я перегрузил эти методы get_form_kwargs (), чтобы предоставить моим Forms экземпляр «запроса». Если вы не хотите, чтобы объект Request был передан в форму, просто удалите эти перегруженные методы. Если вы хотите их использовать, следуйте этому примеру:

 from django.forms import ModelForm class RequestModelForm(ModelForm): """ Sub-class the ModelForm to provide an instance of 'request'. It also saves the object with the appropriate user. """ def __init__(self, request, *args, **kwargs): """ Override init to grab the request object. """ self.request = request super(RequestModelForm, self).__init__(*args, **kwargs) def save(self, commit=True): m = super(RequestModelForm, self).save(commit=False) m.owner = self.request.user if commit: m.save() return m 

Это немного больше, чем вы просили, но это помогает узнать, как сделать то же самое для Create and Update views. Эта же общая методология также может быть применена к ListView & DetailView.

MessageMixin

На всякий случай, если кто-то захочет использовать MessageMixin.

 class MessageMixin(object): """ Make it easy to display notification messages when using Class Based Views. """ def delete(self, request, *args, **kwargs): messages.success(self.request, self.success_message) return super(MessageMixin, self).delete(request, *args, **kwargs) def form_valid(self, form): messages.success(self.request, self.success_message) return super(MessageMixin, self).form_valid(form) 

Самый простой способ сделать это – предварительно фильтровать набор запросов:

 from django.views.generic import DeleteView class PostDeleteView(DeleteView): model = Post success_url = reverse_lazy('blog:list_post') def get_queryset(self): owner = self.request.user return self.model.objects.filter(owner=owner) 

Я бы предложил, чтобы лучший (и самый простой) способ сделать это – использовать UserPassesTestMixin который дает вам более UserPassesTestMixin разделение проблем.

Пример:

 from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.views.generic import DeleteView class MyDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView): def test_func(self): """ Only let the user access this page if they own the object being deleted""" return self.get_object().owner == self.request.user 
Давайте будем гением компьютера.