[PYTHON] Web App Development Practice: Create a Shift Creation Page with Django! (Design of database model)

** This is a continuation of Last time (corrected on April 4, 2014). ** **

1. Selection of necessary data

First, I thought about what kind of data the app might need. The information needed when thinking about shifts is likely to be roughly divided into two types.

-** Staff data ** -** User data **

In each case, there is basic information such as names, personal information that is difficult to express as data such as experience and skill for staff, past career and personality for users, but ** At the moment, the former basics Information is enough. ** Personal information like the latter should be known to all facility staff, even if they don't like it, so I don't think it's necessary to force it into data.

So, for the time being, I tried to keep it as simple as possible.

staff

user

After that, you have to save the data of the schedule you actually made.

Schedule

-** Staff shift ** -** User's plan **

In addition, define the shift table administrator (editor) and staff (viewer). It would be a problem if anyone who accessed it could view and edit it.

owner

-** Administrator account information ** -** Staff account information (plural) **

As mentioned above, I will do it like this.

2. Model definition

startprojectAfter creating a django project instartappMake an app with.

I felt that one app would be enough, but I didn't like it because it seemed to be messy later, so I decided to split it first (same as I thought above,'staff' ,'guest','schedule','owner'). Before forgetting each, add them to INSTALLED_APPS in settings.py and write models.py.

Let's start with the staff.

staff/models.py

from django.db import models
from django.contrib.auth.models import User
from owner.models import GroupSchedule


class Staff(models.Model):
	groupschedule = models.ForeignKey(GroupSchedule)

	name = models.CharField(max_length=40)

	user = models.OneToOneField(User,null=True,blank=True)

	class Meta:
		unique_together = ( ('name','groupschedule',), )

	def __unicode__(self):
		return self.name

At the moment, Staff is the only model class. 1.groupschedule: In order to determine which shift table the staff belongs to (so that the staff of multiple shift tables are not mixed up), we are linking it with a model called Group Schedule of the owner app. I will talk about the contents of this later. 2.name: As you can see, it's the name of the staff. 3.user: Assuming that the staff will create an account and log in and browse, it is possible to associate it with the built-in model class User (including name, password, etc.). However, some people do not touch the computer at work, so it is not a required item (blank = True may not be necessary? I do not understand the distinction between null and blank here ...). 4.Meta: You can add something like advanced settings here. unique_together sets a combination of tables that you do not want to duplicate (it seems that this combination can be multiple).

Next is guest.

guest/models.py

from django.db import models
from owner.models import GroupSchedule


class Guest(models.Model):
	groupschedule = models.ForeignKey(GroupSchedule)

	name = models.CharField(max_length=40)

	class Meta:
		unique_together = ( ('name','groupschedule',), )

	def __unicode__(self):
		return self.name

It's almost the same as staff. These may be called each time you want to add another working app to your project.

** The table that seems to be unique to the shift production page is defined in the model of the schedule app (so this is overwhelmingly large for now). ** **

schedule/models.py

from django.db import models
from django.core.validators import MaxValueValidator,MinValueValidator
from owner.models import GroupSchedule
from staff.models import Staff
from guest.models import Guest


#### base classes ####

class Date(models.Model):

	date = models.DateField()

	def strfdate(self):
		return self.date.strftime('%Y/%m/%d,%a')

	class Meta:
		abstract = True	# This class is not make table


class TimeTable(models.Model):
	start = models.TimeField(default='00:00')
	end = models.TimeField(default='00:00')

	def strftimetable(self):
		timef = '%H:%M'
		start,end = self.start,self.end
		return "%s ~ %s" % ( start.strftime(timef),end.strftime(timef) )

	class Meta:
		abstract = True	# This class is not make table


#### main classes ####

###### staff ######
class MonthShift(models.Model):
	year = models.PositiveIntegerField(validators=[MinValueValidator(1),])

	month = models.PositiveIntegerField(validators=[MaxValueValidator(12),MinValueValidator(1),])

	groupschedule = models.ForeignKey(GroupSchedule)

	completed = models.BooleanField(default=False)

	class Meta:
		unique_together = ( ('year','month','groupschedule',), )


class WorkTime(TimeTable):
	groupschedule = models.ForeignKey(GroupSchedule)

	title = models.CharField(max_length=50,unique=True)

	simbol = models.CharField(max_length=5,unique=True)

	def save(self,*args,**kwargs):
		from datetime import time
		if self.start >= self.end:
			WorkTime.objects.create(title=self.title+'2',simbol='-',start=time(0,0),end=self.end)

			self.end = time(23,59)
		super(WorkTime,self).save(*args,**kwargs)

	class Meta:
		unique_together = ( ('groupschedule','title',),('groupschedule','simbol',), )

	def __unicode__(self):
		return self.title


class StaffSchedule(Date):
	staff = models.ForeignKey(Staff,unique_for_date='date')

	worktime = models.ForeignKey(WorkTime)

	leader = models.BooleanField(default=False)

	phoner = models.BooleanField(default=False)

	def __unicode__(self):
		return self.strfdate()


class NgShift(Date):
	staff = models.ForeignKey(Staff,unique_for_date='date')

	ng_shift = models.ManyToManyField(WorkTime)

	def ng_values(self):
		values = self.ng_shift.values_list('title')
		
		return ",".join( reduce( lambda x,y:x + y ,values ) )
	
	def __unicode__(self):
		return self.staff.name


###### guest ######
class GuestSchedule(Date,TimeTable):
	guest = models.ForeignKey(Guest,unique_for_date='date')

	def __unicode__(self):
		return self.strfdate()

'base classes' are the parent classes, ** syncdb doesn't create a table **. 'main classes' are the classes that actually create the table.

1.MonthShift: Define which group, what year, and month of shift, and whether it is complete (for example, on the shift edit page, if you press the "Finish" button, all blank working hours will be converted to holidays, I want to make it like that). The maximum and minimum values are set by validators for both year and month. 2.WorkTime: Define working hours patterns such as "early shift" and "late shift". In my workplace, they are represented by a single letter such as "○" or "△", so I also have an item called symbol. I've overwritten the django built-in method save () and added a process to divide it into daily units if the working hours span two days (I want to express "★" for night shift and "-" for dawn. So I will register it as another pattern). 3.StaffSchedule: Means staff appointments by date. Normally, when distributing shifts, we summarize this on a monthly basis. Make it possible to select only one WorkTime data with ForeignKey. I made it because the item of whether it is a day shift or a night shift was also in the current table. 4.NgShift: You can select multiple WorkTime data in ManyToManyField. It feels like you can register if the staff says, "This time is not possible on this day" (all selections are real holiday wishes). ng_values is a handmade function that returns registered ng_shifts as comma separated strings, but this is for admin pages. 5.GuestSchedule: It is similar to StaffSchedule, but the usage time of customers is different from working hours and it seems difficult to pattern it, so it is a manual input format.

Finally, the information for the administrator is summarized in the owner.

owner/models.py

from django.db import models
from django.contrib.auth.models import User,Group
from django.core.validators import MaxValueValidator,MinValueValidator


class GroupSchedule(models.Model):
	group = models.OneToOneField(Group)

	owner = models.OneToOneField(User)

	start_point = models.PositiveIntegerField(default=1,validators=[MaxValueValidator(31),MinValueValidator(1),])

	def get_calendar(self,year,month):
		from calendar import Calendar

		from datetime import date
		cal_start = date( year,month,self.start_point )
		cal_end = cal_start.replace(month=cal_start.month+1)
		
		this_month = list( Calendar().itermonthdates( year,month ) )
		next_month = list( Calendar().itermonthdates( year,month+1 ) )
		
		wcal = this_month + next_month
		wcal_list = wcal[wcal.index(cal_start):wcal.index(cal_end)]

		return sorted( set(wcal_list),key=wcal_list.index )

	def __unicode__(self):
		return self.group.name

1.GroupSchedule: You can decide which group it is scheduled for, who the owner is, and register the starting point of each month at start_point (at my workplace, it changed a little from the 15th of every month to a month, so you can set it freely. I made it into a shape that I can do). get_calendar is a function that returns a set of dates for one month from the start point, but you will probably call it in view.

Now, I think you have built a basic database.

Next time, let's try "Experiment on admin page".

Recommended Posts

Web App Development Practice: Create a Shift Creation Page with Django! (Design of database model)
Web App Development Practice: Create a Shift Creation Page with Django! (Shift creation page)
Web App Development Practice: Create a Shift Creation Page with Django! (Introduction)
Web App Development Practice: Create a Shift Creation Page with Django! (Authentication system processing)
Web App Development Practice: Create a Shift Creation Page with Django! (Experiment on admin page)
Create a Todo app with Django ③ Create a task list page
Create a simple web app with flask
Create a Todo app with Django ④ Implement folder and task creation functions
Create a Todo app with Django REST Framework + Angular
Create a Todo app with the Django REST framework
Create a Todo app with Django ⑤ Create a task editing function
Create a homepage with django
Create a web API that can deliver images with Django
Create a Todo app with Django ① Build an environment with Docker
[python, ruby] fetch the contents of a web page with selenium-webdriver
Build a web application with Django
Create a file uploader with Django
Create a web app that can be easily visualized with Plotly Dash
A series of amateur infrastructure engineers touching Django with Docker (2): Creating a model
"Trash classification by image!" App creation diary day3 ~ Web application with Django ~
WEB application development using Django [Model definition]
Play like a web app with ipywidgets
Create a model for your Django schedule
Create a GUI app with Python's Tkinter
Daemonize a Python web app with Supervisor
Create your first app with Django startproject
Create a web service with Docker + Flask
I made a WEB application with Django
The story of making a web application that records extensive reading with Django
Try creating a web application with Vue.js and Django (Mac)-(1) Environment construction, application creation
I tried to create a model with the sample of Amazon SageMaker Autopilot
Django Tutorial (Blog App Creation) ① --Preparation, Top Page Creation
How to develop a cart app with Django
WEB application development using Django [Admin screen creation]
Create a PDF file with a random page size
Create a page that loads infinitely with python
[Python] Build a Django development environment with Docker
Build a Django development environment with Doker Toolbox
Create a new page in confluence with Python
How to create a multi-platform app with kivy
Create a one-file hello world application with django
Until you create a new app in Django
Extract data from a web page with Python
Create a table of contents with IPython notebook
Create a web page that runs a model that increases the resolution of the image using gradio, which makes it easy to create a web screen