Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » CBV. Как ограничить создание по пользователю? [RSS Feed]

#1 Авг. 9, 2014 12:48:00

iceberg
Зарегистрирован: 2014-08-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

Имеется три связанные между собой модели.

class MyCategory(models.Model):
    caption = models.CharField(max_length=40)
    
    class Meta:
        ordering=['id']
    def __unicode__(self):
        return self.caption
class MyItem(models.Model):
    category = models.ForeignKey(TodoCategory)
    caption = models.CharField(max_length=40)
    description = models.CharField(max_length=512)
    created = models.DateTimeField('Created time'), default=timezone.now)
    createdby = models.ForeignKey(MyUser)
    ....
    class Meta:
        ordering=['created']
        app_label = 'mysmallapp'
        permissions = (
            ('moderate_myitems', 'View, update and delete any myitems'),
        )
    def __unicode__(self):
        return self.caption
    def get_notes(self):
        return MyNote.objects.filter(itemlink=self)
class MyNote(models.Model):
    itemlink = models.ForeignKey(MyItem)
    text = models.CharField(max_length=512)
    created = models.DateTimeField('Created time'), default=timezone.now)
    ...
    
    class Meta:
        ordering=['created']
        app_label = 'mysmallapp'
        permissions = (
            ('moderate_notes', 'View, update and delete any note'),
        )

Первая модель MyCategory проблем не вызывает, ее экземпляры будут создаваться только из админки. Экземпляры двух других моделей тоже нормально создаются, редактируются и удаляются с помощью созданных на основе CBV объектов. Оргпнизация URL выглядит примерно таким образом:

urlpatterns = patterns('',
                       url(r'^item/add/$', login_required(MyItemCreateView.as_view()), 
			   name='myitem_add'),
		       url(r'^item/(?P<pk>\d+)/edit/$', login_required(MyItemEditView.as_view()), 
			   name='myitem_edit'),
		       url(r'^item/(?P<pk>\d+)/delete/$', login_required(MyItemDeleteView.as_view()), 
			   name='myitem_delete'),
		       url(r'^item/(?P<numer>\d+)/add/$', login_required(MyNoteCreateView.as_view()), 
			   name='mynote_add'),
		       url(r'^note/(?P<pk>\d+)/edit/$', login_required(MyNoteEditView.as_view()), 
			   name='mynote_edit'),
		       url(r'^note/(?P<pk>\d+)/delete/$', login_required(MyNoteDeleteView.as_view()), 
			   name='mynote_delete'),
                       )
Теперь встала задача, чтобы каждый пользователь не мог редактировать, удалять и создавать то, что принадлежит другому пользователю.

Для MyItemEditView, MyItemDeleteView, MyNoteEditView и MyNoteDeleteView это делается легко путём переопределения get_queryset.

def get_mynotes_queryset(self):
    if self.request.user.has_perm('mysmallapp.moderate_notes'):
        return MyNote.objects.all()
    else:
        return MyNote.objects.filter(itemlink__createdby=self.request.user)
class MyNoteEditView(UpdateView):
    model = MyNote
    form_class = MyNoteForm
    ...
    get_queryset = get_mynotes_queryset
class MyNoteDeleteView(DeleteView):
    model = MyNote
    template_name = ...
    ...
    
    get_queryset = get_mynotes_queryset

Вопрос: как сделать то же самое для MyItemCreateView и ограничить доступ другим пользователям для создания MyNote, ссылающимся на чужие экземпляры MyItem ?

То есть если некий пользователь идет по ссылке /item/3/add/, а экземпляр MyItem с pk, равным 3, принадлежит другому пользователю, то пользователь отфутболивался ещё до отправки заполненной им формы на создание нового экземпляра MyNote.

Пока что у класса MyNoteCreateView переопределен следующий метод:
    def form_valid(self, form):
        nlink = get_object_or_404(MyItem, pk=self.kwargs['numer'])
        form.instance.itemlink = nlink
        return super(MyNoteCreateView, self).form_valid(form)

Отредактировано iceberg (Авг. 9, 2014 12:56:05)

Офлайн

#2 Авг. 10, 2014 12:33:16

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

Переопределяйте dispatch, если юзер пытается сделать бяку райзим PermissionDenied, до гета и поста дело вообще не дойдет, а до form_valid и прочих специфических методов тем более. Разумно организовать это в виде миксина.



Офлайн

#3 Авг. 10, 2014 13:16:57

iceberg
Зарегистрирован: 2014-08-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

С dispatch кажется понял, спасибо, а вот про миксины можно ткнуть пальцем хотя бы направление? О миксинах в документации почитал, но поскольку до сих пор не могу полностью привыкнуть к CBV, с решением пока не сориентируюсь.

Офлайн

#4 Авг. 10, 2014 13:24:23

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

Ок, в чем преимущество CBV перед классическими вьюхами-функциями?
В наследовании, во множественном наследовании. Миксин - это такой класс, который сам по себе не может быть представлением, но участвуя в наследовании он наделяет другие классы полезными свойствами.

class PermissionResolverMixin(object):
    def dispatc(self, request, *args, **kw):
        if ....
              self.item = ...
        else:
              raise PermissionDenied()
        return super(PermissionResolverMixin, self).dispatc(self, request, *args, **kw)
class MyView(PermissionResolverMixin, UpdateView):
     pass

Ваша вьюшка теперь имеет self.item или вернет 403.



Офлайн

#5 Авг. 10, 2014 13:25:18

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

iceberg
Когдап говорят спасибо, ставят не минус, а плюс.



Офлайн

#6 Авг. 10, 2014 13:38:03

iceberg
Зарегистрирован: 2014-08-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

FishHook
icebergКогдап говорят спасибо, ставят не минус, а плюс.
Вау, не знаю, как так получилось, конечно же имел в виду плюс. Сам в шоке. А как теперь это можно исправить? С радостью удалил бы свой минус из кармы, но нет такой возможности. Просьба администрации поменять в посте мой минус на плюс.

Офлайн

#7 Авг. 11, 2014 12:43:32

iceberg
Зарегистрирован: 2014-08-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

Сделал через переопределение dispatch без миксинов. С миксинами тоже разобрался, меня смутило использование в методах миксинов атрибутов, которых у них может не быть, не дошло, что наследование производится не от одного миксина, а от двух классов.

FishHook, спасибо за наводку.

Ок, в чем преимущество CBV перед классическими вьюхами-функциями?
Концептуально может быть преимущества и нет, но под CBV уже создано много полезных классов и глупо ими не пользоваться. Если говорить об отдельно взятой вьюхе, раз уж остальное написано в CBV, пусть и эта будет тоже. Как выяснилось, это не так сложно.

Офлайн

#8 Авг. 11, 2014 13:25:19

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

CBV. Как ограничить создание по пользователю?

iceberg
Концептуально может быть преимущества и нет
Конечно, есть. Ровно те же преимущества, которые есть у ООП относительно процедурного программирования.



Офлайн

  • Начало
  • » Django
  • » CBV. Как ограничить создание по пользователю?[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version