galaxy: big refactor

Main changes:
  - Multiple Galaxy objects can now exist at the same time in DB. This allows for ruling a new galaxy while still
    displaying the old one.
  - The criteria to quickly know whether a user is a possible citizen is now a simple query on picture count. This
    avoids a very complicated query to database, that could often result in huge working memory load. With this change,
    it should be possible to run the galaxy even on a vanilla Postgres that didn't receive fine tuning for the Sith's
    galaxy.
This commit is contained in:
Skia
2023-04-14 17:33:11 +02:00
parent 1aa3bb8cc4
commit 31093fff43
7 changed files with 339 additions and 196 deletions

View File

@ -45,32 +45,29 @@ class GalaxyUserView(CanViewMixin, UserTabsMixin, DetailView):
def get_object(self, *args, **kwargs):
user: User = super(GalaxyUserView, self).get_object(*args, **kwargs)
if not hasattr(user, "galaxy_user"):
if user.current_star is None:
raise Http404(_("This citizen has not yet joined the galaxy"))
return user
def get_queryset(self):
return super(GalaxyUserView, self).get_queryset().select_related("galaxy_user")
def get_context_data(self, **kwargs):
kwargs = super(GalaxyUserView, self).get_context_data(**kwargs)
kwargs["lanes"] = (
GalaxyLane.objects.filter(
Q(star1=self.object.galaxy_user) | Q(star2=self.object.galaxy_user)
Q(star1=self.object.current_star) | Q(star2=self.object.current_star)
)
.order_by("distance")
.annotate(
other_star_id=Case(
When(star1=self.object.galaxy_user, then=F("star2__owner__id")),
When(star1=self.object.current_star, then=F("star2__owner__id")),
default=F("star1__owner__id"),
),
other_star_mass=Case(
When(star1=self.object.galaxy_user, then=F("star2__mass")),
When(star1=self.object.current_star, then=F("star2__mass")),
default=F("star1__mass"),
),
other_star_name=Case(
When(
star1=self.object.galaxy_user,
star1=self.object.current_star,
then=Case(
When(
star2__owner__nick_name=None,
@ -101,4 +98,4 @@ class GalaxyUserView(CanViewMixin, UserTabsMixin, DetailView):
class GalaxyDataView(FormerSubscriberMixin, View):
def get(self, request, *args, **kwargs):
return JsonResponse(Galaxy.objects.first().state)
return JsonResponse(Galaxy.get_current_galaxy().state)