Oleg Komarov
ac49e9d5f6
This change solves a blocker for an upcoming drop of Version.file field: calculating `Extension.latest_version` relied on having `VersionFiles` already populated, but it was triggered on `Version.save()`, which happened before the cross table could be populated. One functional change is that a Version object is now created in NewVersionView, immediately after the File is saved, and not in NewVersionFinalizeView, as before. Tests are rewritten to require only FileFactory, the Extension and Version objects are created as it is done in the actual production code. This loses a bit on the ergonomics of factories, but overall makes the state of test objects more consistent, often simplifying the test code. VersionFactory is no longer needed, and has been cleaned up. ExtensionFactory is only used in construct_fake_notifications, and could also be replaced with an in-memory object constructed manually. Reviewed-on: #191 Reviewed-by: Anna Sirota <annasirota@noreply.localhost>
65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
from django.contrib.auth.mixins import UserPassesTestMixin
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
from extensions.models import Extension
|
|
from files.models import File
|
|
|
|
|
|
class OwnsFileMixin(UserPassesTestMixin):
|
|
def dispatch(self, *args, **kwargs):
|
|
self.file = get_object_or_404(File, pk=self.kwargs['pk'])
|
|
return super().dispatch(*args, **kwargs)
|
|
|
|
def test_func(self) -> bool:
|
|
return self.file.user == self.request.user
|
|
|
|
|
|
class ExtensionQuerysetMixin:
|
|
"""Add reusable methods to class-based views handling Extensions."""
|
|
|
|
def get_extension_queryset(self):
|
|
"""Return queryset with unlisted add-ons for logged in users under certain conditions."""
|
|
if self.request.user.is_staff:
|
|
return Extension.objects.all()
|
|
if self.request.user.is_authenticated:
|
|
return Extension.objects.listed_or_authored_by(self.request.user)
|
|
return Extension.objects.listed
|
|
|
|
|
|
class MaintainedExtensionMixin:
|
|
"""Fetch an extension by slug if current user is a maintainer."""
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
self.extension = get_object_or_404(
|
|
Extension.objects.authored_by(self.request.user),
|
|
slug=self.kwargs['slug'],
|
|
)
|
|
return super().dispatch(*args, **kwargs)
|
|
|
|
|
|
class ListedExtensionMixin:
|
|
"""Fetch a publicly listed extension by slug in the URL before dispatching the view."""
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
self.extension = get_object_or_404(
|
|
Extension.objects.listed.prefetch_related('authors', 'ratings'),
|
|
slug=self.kwargs['slug'],
|
|
)
|
|
return super().dispatch(*args, **kwargs)
|
|
|
|
|
|
class ExtensionMixin:
|
|
"""Fetch an extension by slug in the URL before dispatching the view."""
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
self.extension = get_object_or_404(Extension, slug=self.kwargs['slug'])
|
|
return super().dispatch(*args, **kwargs)
|
|
|
|
|
|
class DraftVersionMixin:
|
|
"""Fetch the version object which is being edited as a draft."""
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
self.version = self.extension.versions.first()
|
|
return super().dispatch(*args, **kwargs)
|