Corban-Lee 5fc0128c7c Venues and Waters - Basic implementation
I've added the model for the Venues, and implemented a basic system for displaying them in the venues and waters page.
2023-10-23 15:42:31 +01:00

235 lines
8.2 KiB
Python

"""Models for the mainapp."""
from django.db import models
from django.core.exceptions import ValidationError
class Venue(models.Model):
"""Represents a Venue and Waters."""
VENUE_TYPES = (
("FISHERY", "Fishery"),
("CLUB", "Club"),
("PRIVATE", "Private")
)
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
extra_notes = models.TextField(blank=True)
venue_type = models.CharField(choices=VENUE_TYPES, max_length=50)
# Contact information
phone_number = models.CharField(max_length=100)
email_address = models.EmailField()
website_url = models.URLField()
# Location information
street_address = models.CharField(max_length=100)
city = models.CharField(max_length=255)
provence = models.CharField(max_length=100)
postal_code = models.CharField(max_length=20)
country = models.CharField(max_length=100)
latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
# Socials information
twitter_url = models.URLField(blank=True)
instagram_url = models.URLField(blank=True)
facebook_url = models.URLField(blank=True)
def __str__(self):
return self.name
# class ReusableAutoField(models.PositiveIntegerField):
# """A django auto field that can reuse deleted primary keys."""
# def get_next_available_id(self, model_cls, using=None):
# """
# Returns the next available id for the given model class.
# """
# all_ids = set(range(1, model_cls._default_manager.count()+1))
# used_ids = set(model_cls._default_manager.all().values_list('pk', flat=True))
# available_ids = all_ids - used_ids
# if available_ids:
# return min(available_ids)
# if used_ids:
# return max(used_ids) + 1
# return 1
# def get_default(self):
# """Returns the default value for this field"""
# return self.get_next_available_id(self.model)
# class SectionValidator:
# """Validation class for the `section` field on the `member` model."""
# def __init__(self, max_value="ZZZ"):
# self.max_value = max_value.upper()
# self.alphabet_size = ord("Z") - ord("A") + 1
# def is_valid(self, section: str, team_sections: list[str]=None) -> bool:
# """Returns boolean if the section passed is valid."""
# section = section.upper()
# if not self._is_alphanumeric(section):
# return False
# if not self._is_in_alphabet(section[0]):
# return False
# if not self._is_in_range(section):
# return False
# if team_sections:
# if not self._is_unique(section, team_sections):
# return False
# if not self._is_not_adjacent(section, team_sections):
# return False
# return True
# def _is_alphanumeric(self, section: str) -> bool:
# """Returns boolean if all characters in the passed string are alphanumerical."""
# return all(c.isalnum() for c in section)
# def _is_in_alphabet(self, c) -> bool:
# """Returns boolean if the passed character is alphabetical."""
# return "A" <= c <= "Z"
# def _is_in_range(self, section) -> bool:
# """Returns boolean if the passed section less or equal to the max value."""
# section_value = self._section_value(section)
# max_value = self._section_value(self.max_value)
# return section_value <= max_value
# def _is_unique(self, section, team_sections) -> bool:
# """Returns boolean if the passed section is unique amongst `team_sections`."""
# return section not in team_sections
# def _is_not_adjacent(self, section, team_sections) -> bool:
# """Returns boolean if the passed section is not adjacent to any `team_sections`."""
# for team_section in team_sections:
# team_section_value = self._section_value(team_section)
# section_value = self._section_value(section)
# if abs(team_section_value - section_value) <= 1:
# return False
# return True
# def _section_value(self, section):
# """Returns the value of the passed section."""
# n = len(section)
# value = sum((ord(c) - ord("A") + 1) * self.alphabet_size ** (n - i - 1) for i, c in enumerate(section))
# return value
# class SectionManager(models.Manager):
# @staticmethod
# def get_max_section():
# max_section = None
# max_number = -1
# # Iterate through all sections in the database
# for section in Section.objects.all():
# section_name = section.name
# section_number = 0
# # Calculate the section number based on the section name
# for i, char in enumerate(section_name):
# section_number += (ord(char) - ord('A') + 1) * (26 ** (len(section_name) - i - 1))
# # Check if this section has a higher number than the current maximum
# if section_number > max_number:
# max_number = section_number
# max_section = section_name
# return max_section
# @staticmethod
# def find_next_section(current_section):
# if not current_section:
# return 'A'
# # Split current section name into a list of characters
# chars = list(current_section)
# # Increment the last character
# chars[-1] = chr(ord(chars[-1]) + 1)
# # Check if the last character is "Z", and carry over to the next character if necessary
# for i in range(len(chars) - 1, -1, -1):
# if chars[i] > 'Z':
# chars[i] = 'A'
# if i == 0:
# # If the first character needs to be incremented, add a new character "A"
# chars.insert(0, 'A')
# else:
# # Increment the previous character
# chars[i - 1] = chr(ord(chars[i - 1]) + 1)
# else:
# break
# # Join the characters back into a string and return the result
# return ''.join(chars)
# class Section(models.Model):
# """Represents a fishing area. Members can be assigned to a section,
# but no 2 teammates can be in the same or adjacent section."""
# character = models.CharField(max_length=3, unique=True, null=False)
# objects = SectionManager()
# def clean(self):
# super().clean()
# self.character = self.character.upper()
# def __str__(self) -> str:
# return self.character
# class Member(models.Model):
# """Represents a member of a team"""
# first_name = models.CharField(max_length=255)
# last_name = models.CharField(max_length=255)
# team = models.ForeignKey("Team", on_delete=models.SET_NULL, null=True, blank=True, related_name='members')
# peg_number = models.PositiveIntegerField(null=True, editable=True, unique=True)
# section = models.ForeignKey(to=Section, on_delete=models.SET_NULL, null=True, swappable=True, related_name='members')
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
# # If the peg_number field is not set, we assign it the smallest
# # available positive integer, excluding any used values.
# if not self.peg_number:
# used_peg_numbers = Member.objects.exclude(id=self.id).exclude(peg_number=None).values_list("peg_number", flat=True)
# peg_numbers = set(range(1, Member.objects.count() + 1)) - set(used_peg_numbers)
# if peg_numbers:
# self.peg_number = min (peg_numbers)
# def __str__(self):
# return f"{self.first_name} {self.last_name} (team {self.team.number}) [section {self.section.character}]"
# @property
# def fullname(self) -> str:
# return f"{self.first_name} {self.last_name}"
# class Team(models.Model):
# """Represents a team"""
# number = models.PositiveIntegerField(unique=True, null=False, blank=False)
# def __str__(self):
# return f"Team {self.number}"