Django: How to create some variable in model based on the foreign key data?

Viewed 73

I am new to Django and right now I am working on my first project: sits reservation system for some cinema. For this I have created 3 models: Movie, Hall and Event. Hall generates sits map as array.

class Hall(models.Model):
HALL_NAME = (
    ('A', 'Hall A'),
    ('B', 'Hall B'),
    ('C', 'Hall C')
)
hall_name = models.CharField(choices=HALL_NAME, max_length=30)
hall_structure = models.CharField(max_length=10000, default=generate_sits(hall_name))

@property
def get_sits(self):
    if self.hall_name == 'A':
        return generate_sits('A')
    if self.hall_name == 'Hall B':
        return generate_sits('B')
    if self.hall_name == 'Hall C':
        return generate_sits('C')
    else:
        return "lol"

def __str__(self):
    return f'{self.hall_name}'

After that i would like to create a variable for Event model, which takes the array structure of the sits, turns it into dictionary (Example ['A1': 'empty', 'A2': 'empty', ...] ). I want this variable to be overwritten in the future, when someone should book a sit on the vebsite (['A1': 'reserved']).

Here is my Event model:

class Event(models.Model):

EVENT_DAYS = (
    ('mon', 'Monday'),
    ('tu', 'Tuesday'),
    ('we', 'Wednesday'),
    ('th', 'Thursday'),
    ('fr', 'Friday'),
)

EVENT_TIME_SLOT = (
    ('10', '10:00'),
    ('13', '13:30'),
    ('17', '17:00'),
    ('20', '20:30'),
    ('00', '00:00'),
)

EVENT_TYPE = (
    ('2d', '2D'),
    ('3d', '3D'),
)

end_default = "for this Event was assigned yet"
days_default = "No day "
time_default = "No time "
hall_default = "No hall "

week_day = models.CharField(max_length=10, choices=EVENT_DAYS, default=days_default + end_default)
time_slot = models.CharField(max_length=10, choices=EVENT_TIME_SLOT, default=time_default + end_default)
type = models.CharField(max_length=2, choices=EVENT_TYPE, default=EVENT_TYPE[0])
hall = models.ForeignKey(Hall, on_delete=models.CASCADE)

film = models.ForeignKey(Movie, on_delete=models.CASCADE)

start_date = models.DateField(auto_now_add=False, auto_now=False, blank=True)
end_date = models.DateField(auto_now_add=False, auto_now=False, blank=True)

def __str__(self):
    return f'{self.film.name}'

And i tried here something like this:

    default_sits_map = dict.fromkeys(hall.get_sits, 'Empty')

But as i have realised, you can't access a class in this way (like it is an object).

I really dont get it right now how to create such updatable variable for every event, based on the hall structure. I thank everyone in advance, who took his time to read this and gave his opinion on this topic.

UPDATE:

here is also the code for the function, which generates a list with sit places according to the hall name (A, B or C)

def generate_sits(_hall: str):
sits = []
row = int()

if _hall == 'A' or _hall == 'B' or _hall == 'C':
    if _hall == 'A':
        row = 14
    if _hall == 'B':
        row = 12
    if _hall == 'C':
        row = 9

    # sits setting begins here
    for i in range(row):
        i = i + 1
        sits.append("A" + str(i))
    for i in range(row):
        i = i + 1
        sits.append("B" + str(i))
    for i in range(row):
        i = i + 1
        sits.append("C" + str(i))
    for i in range(row):
        i = i + 1
        sits.append("D" + str(i))

    # if hall is "A" or "B" - they get more sits then "C"
    if _hall == 'A' or _hall == 'B':

        for i in range(row):
            i = i + 1
            sits.append("E" + str(i))
        for i in range(row):
            i = i + 1
            sits.append("F" + str(i))

return json.dumps(sits)
1 Answers

I solved the problem by restructurizing the project a little bit. The rows and columns of the specific Hall are now just stored in the model:

Models.py

class Hall(models.Model):
HALL_NAME = (
    ('A', 'Hall A'),
    ('B', 'Hall B'),
    ('C', 'Hall C')
)

hall_name = models.CharField(choices=HALL_NAME, max_length=30)
hall_sits = models.IntegerField()
hall_cols = models.IntegerField()

def __str__(self):
    return f'{self.hall_name}'

Using this I was able to generate a new event map html/css grid from views:

Views.py

def event_map(request, slug, event_id):
selected_event = Event.objects.get(pk=event_id)

movie = selected_event.film
hall = selected_event.hall
time = selected_event.get_time_slot_display()
date_event = selected_event.get_week_day_display()

sits = list(range(0, hall.hall_sits))
cols = list(range(0, hall.hall_cols))
# and so on

And moved the checking of the reserved places to the description of the Invoice Model:

Models.py

class Invoice(models.Model):
user = models.ForeignKey(UserPersonalData, on_delete=models.CASCADE, 
blank=True, null=True)
total_price = models.FloatField()
email = models.CharField(max_length=320)
invoice_details = models.CharField(max_length=2048)
invoice_key = models.CharField(editable=False, max_length=12, default=generate_invoice_key())
event = models.ForeignKey(Event, on_delete=models.CASCADE)

def __str__(self):
    return f'{self.email} {self.invoice_key}'
Related