Как убедиться, что пользователи получают только к DetailView, Listview и UpdateView свои собственные созданные объекты - PullRequest
0 голосов
/ 06 мая 2019

Я создал простое приложение, в котором вошедшие в систему пользователи могут отправлять сеанс для конференции, просматривать результаты их представления, просматривать список их представлений и редактировать свои представления (они не должны иметь доступа к другим пользователям). представления). Я использую представления на основе классов django (CreateView, DetailView, ListView, UpdateView).

Однако я борюсь с разрешениями. Все представления, кроме updateview, работают, но если я ввожу URL-адрес напрямую, используя незарегистрированное имя пользователя, я могу увидеть их представления.

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

Чего мне не хватает? И есть ли лучший способ избежать использования имен пользователей и слагов в URL? Кажется, я не могу найти ни примеров, ни советов, как это делать. Я новичок, поэтому, возможно, мне не хватает понимания основ здесь и там.

Я попытался понять, как работает модель User, потому что там мне удалось найти способ создавать, просматривать и редактировать данные пользователя защищенным способом. Хотя я полагался на функциональные представления и не могу применить этот подход к приложению представления.

models.py

class Hsession(models.Model):

submitter = models.ForeignKey(User, related_name="submittersessions", on_delete=models.CASCADE)
submission_date = models.DateTimeField(auto_now=True)
session_title = models.CharField("session title", max_length=40, default='')
session_description = models.TextField("session description", max_length=350, default='')
slug = models.SlugField(allow_unicode=True, unique=True)

def save(self, *args, **kwargs):
    self.slug = slugify(self.session_title)
    super().save(*args, **kwargs)

def get_absolute_url(self):
    return reverse("submission:detail-single", kwargs={"username": self.submitter.username, "slug": self.slug})

URLs:

urlpatterns = [
    path("", views.CreateSubmission.as_view(), name="create"),
    path("by/<username>/<slug>",views.SubmissionDetail.as_view(),name="detail-single"),
    path("by/<slug>/edit",views.EditSubmission.as_view(), name="edit"),
    path("by/<username>/",views.SubmissionList.as_view(), name="list"),
    ]

views.py

class CreateSubmission(LoginRequiredMixin, generic.CreateView):

    fields = ('session_title', 'session_description', 'subject_category')
    model = models.Hsession

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.submitter = self.request.user
        self.object.save()
        return super().form_valid(form)

class SubmissionList(LoginRequiredMixin, generic.ListView):

    model = models.Hsession
    template_name = "submission/user_hsession_list.html"

    def get_queryset(self):

        try:
            self.hsession_submitter = User.objects.prefetch_related("submittersessions").get(
                username__iexact=self.kwargs.get("username")
            )
        except User.DoesNotExist:
            raise Http404
        else:
            return self.hsession_submitter.submittersessions.all()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["hsession_submitter"] = self.hsession_submitter
        return context

class SubmissionDetail(LoginRequiredMixin, generic.DetailView):

    model = models.Hsession

     def get_queryset(self):
         queryset = super().get_queryset()
         return queryset.filter(
            submitter__username__iexact=self.kwargs.get("username")
         )

class EditSubmission(LoginRequiredMixin, generic.UpdateView):
    model = models.Hsession
    fields = ('session_title', 'session_description', 'subject_category')
    template_name = 'submission/hsession_update.html'
    success_url = 'submission/hsession_detail.html'

forms.py

class UserSubmissionForm(ModelForm):
    class Meta:
        model = Hsession
        fields = ['session_title','session_description', 'subject_category']

class EditSubmissionForm(ModelForm):
    class Meta:
        model = Hsession
        fields = ['session_title','session_description', 'subject_category']

1 Ответ

0 голосов
/ 06 мая 2019

Вы должны использовать UserPassesTestMixin вот так

from django.contrib.auth.mixins import UserPassesTestMixin

class EditSubmission(UserPassesTestMixin,LoginRequiredMixin, generic.UpdateView):
   model = models.Hsession
   fields = ('session_title', 'session_description', 'subject_category')
   template_name = 'submission/hsession_update.html'
   success_url = 'submission/hsession_detail.html'

   def test_func(self):
       //should return true if he have access
       if self.request.user.is_authenticated:
          slug = self.kwargs['slug']
          obj = self.model.objects.get(slug=slug)
          login_user = self.request.user
          return login_user.pk == obj.submitter.pk
       else:
           return False     

для получения дополнительной информации UserPassesTestMixin

...