I'd really appreciate some guidance on how to construct the following models. I want to make sure I'm doing this in the ideal way.
I want to keep track of some info about employees at my work. Basically, past Education and past Work Experience
So here's the relations I can think of
Education
An employee could been to several school and each school can have many students (m2m)
Students attend a school for a period of time
a student can have multiple degrees form the same school and that school offers multiple degrees (m2m)
Work (almost the same as education)
m2m relation with employees and companies
employees work at a company to a set time
employes could have several jobs at one company (m2m)
Following basically what's above, here's the code I've worked out:
#make a list of numbers in a tuple
START_DATE_CHOICES = dict((str(x),str(x)) for x in range(date.today().year-30,date.today().year+1))
END_DATE_CHOICES = START_DATE_CHOICES
START_DATE_CHOICES = START_DATE_CHOICES.items()
START_DATE_CHOICES.sort()
START_DATE_CHOICES.reverse()
START_DATE_CHOICES = tuple(START_DATE_CHOICES)
END_DATE_CHOICES['current'] = 'current'
END_DATE_CHOICES = END_DATE_CHOICES.items()
END_DATE_CHOICES.sort()
END_DATE_CHOICES.reverse()
END_DATE_CHOICES = tuple(END_DATE_CHOICES)
#both schools and companies
class Institution(models.Model):
name = models.CharField(max_length = 75)
class Education(models.Model):
DEGREE_CHOICES = (
('A.A.', 'Associate'),
('Minor', 'Minor'),
('B.A.', 'Bachelor of Arts'),
('B.S.', 'Bachelor of Science'),
('Masters', 'Masters'),
('Ph. D.', 'Doctor of Philosophy'),
)
school = models.ManyToManyField(Institution, through='Dates')
degree = models.CharField(max_length = 5, choices = DEGREE_CHOICES, null = True)
subject = models.CharField(max_length = 20, null = True)
class Work(models.Model):
company = models.ManyToManyField(Institution, through='Dates')
position = models.CharField(max_length = 50, null = True)
jobDescription = models.TextField(null = True)
class Dates(models.Model):
education = models.ForeignKey(Education, null = True)
work = models.ForeignKey(Work, null = True)
institution = models.ForeignKey(Institution)
start = models.CharField(max_length = 4, choices = START_DATE_CHOICES)
end = models.CharField(max_length = 7, choices = END_DATE_CHOICES)
class Person(models.Model):
....
school = models.ManyToManyField(Institution, blank=True)
education = models.ManyToManyField(Education, blank = True)
company = models.ManyToManyField(Institution, blank = True, related_name="%(app_label)s_%(class)s_related")
work = models.ManyToManyField(Work, blank=True)
....
So my question is: Is this an acceptable way of doing it? I'm a newbie and I'm not sure if I'm just abusing relationships
also, I'm sure there's a easier way to do the whole start/end date thing... wasn't able to figure it out though
Any pointers would be greatly appreciated, Thank you!
For many to many fields you should use the plural form. for Person that would be educations and jobs for instance.
Also it is convention to write job_description instead of jobDescription in model fields.
In Person the fields school and company are redundant because that information is accessible through educations (currently education) and jobs (currently work) respectively.
I think you don't need the many to many field company in Work. A simple ForeignKey should suffice. I think you only have a specific job at ONE company for a given time. You can have mutliple jobs at the same time at multiple companies but still every job is at a single employer. Or am I wrong?
The same goes for Education. You only have a degree in a specific subject from one school even if you went to several schools in the course of this education. Or do you want to model that situation that accurately?
The naming of all dates is a bit misleading since they all are acually years. You also could use NULL in the end year as 'current' and use PositiveIntegerFields.
Now I would have this code:
#both schools and companies
class Institution(models.Model):
name = models.CharField(max_length = 75)
class Education(models.Model):
DEGREE_CHOICES = (
('A.A.', 'Associate'),
('Minor', 'Minor'),
('B.A.', 'Bachelor of Arts'),
('B.S.', 'Bachelor of Science'),
('Masters', 'Masters'),
('Ph. D.', 'Doctor of Philosophy'),
)
school = models.ForeignKey(Institution)
degree = models.CharField(max_length = 5, choices = DEGREE_CHOICES, null = True)
subject = models.CharField(max_length = 20, null = True)
start_year = models.PositiveIntegerField()
end_year = models.PositiveIntegerField(null=True)
class Job(models.Model):
company = models.ForeignKey(Institution)
position = models.CharField(max_length = 50, null = True)
job_description = models.TextField(null = True)
start_year = models.PositiveIntegerField()
end_year = models.PositiveIntegerField(null=True)
class Person(models.Model):
....
educations = models.ManyToManyField(Education, blank = True)
jobs = models.ManyToManyField(Work, blank=True)
....
Of course if you want to have choices for the years you can have them
YEAR_CHOICES = ((year, str(year)) for year in range(...))
Alternatively you could write a custom validator for your year fields.
Related
I have a simple model.
models.py
class Content(models.Model):
title = models.CharField(max_length = 300, unique = True)
category = models.CharField(max_length = 50)
def __str__(self):
return self.title
then I'm scraping the data from some sources and want to store in this table.
toi_r = requests.get("some source")
toi_soup = BeautifulSoup(toi_r.content, 'html5lib')
toi_headings = toi_soup.findAll("h2", {"class": "entry-title format-icon"})[0:9]
toi_category = toi_soup.findAll("a", {"class": ""})[0:9]
toi_news = [th.text for th in toi_headings]
toi_cat = [tr.text for tr in toi_category]
for th in toi_headings:
toi_news.append(th.text)
for tr in toi_category:
toi_cat.append(tr.text)
for title, category in zip(toi_news, toi_cat):
n = Content.objects.create(title=title, category=category)
So here, error is UNIQUE Constraint failed. So, If I remove the UNIQUE Constraint, then everything works but mulitple copies of data are stored as the page refreshes. Is there any other way to work with this?
can someone help me and teach me what happens?
For me not to make mistakes again?
I want to bind a foreign key (class category) to my course class. And I did something that doesn't allow me to get out of it.
Error: django.db.utils.IntegrityError: The row in table 'courses_course'
with primary key '3' has an invalid foreign key:
courses_course.category_id contains a value 'outros' that does not have a
corresponding value in courses_category.id.
CATEGORY = [('eng','ENGENHARIA'),('prog','PROGRAMAÇÃO'),('hum','HUMANAS'),('saude','SAÚDE'),
('outros','OUTROS')] // i'm from brazil
class Category(models.Model):
title_category = models.CharField('Nome da Categoria', max_length= 63 , choices = CATEGORY )
class Course(models.Model):
title = models.CharField('Nome', max_length= 100)
slug = models.SlugField('Atalho',max_length=50)
description = models.TextField('Descricao',blank = True)
follows = models.IntegerField(default = 0) //allows negative numbers, I know. I'll fix it ...
imagem = models.ImageField(upload_to = 'courses/images',verbose_name= 'Imagem',
null=True, blank = True)
category = models.ForeignKey('Category', on_delete = models.CASCADE)
created_at = models.DateTimeField('Criado em',auto_now_add = True )
updated_at= models.DateTimeField( 'Atualizado em', auto_now = True )
Does anyone imagine another structure or class that allows you to create educational courses / videos that have categories? Or am I on the right track for a beginner?
The only thing I can guess with the information you gave (you didn't say WHEN you get this error) is that you tried to do something such as :
my_course.category = 'outros'
my_course.save()
Which is incorrect since it isn't a Category object. A ForeignKey field must refer to an object of type to which you point to.
category = Category.objects.create(title_category='outros')
my_course.category = category
my_course.save()
This would work since you give a reference to a Category object in your Course object.
Do not hesitate to read the documentation about ForeignKey fields again.
How can I get all the laws from all the courses that an specific user is subscribed?
class Law(models.Model):
name = models.CharField('Nome', max_length=100)
slug = models.SlugField('Atalho')
description = models.TextField('Description', blank = True, null=True)
class Course(models.Model):
name = models.CharField('Nome', max_length=100)
slug = models.SlugField('Atalho')
description = models.TextField('Descrição', blank = True, null=True)
laws = models.ManyToManyField(Law, related_name='law_course')
class Subscription(models.Model):
STATUS_CHOICES=(
(
(0, 'Pendente'),
(1, 'Approved'),
(2, 'Canceled'),
)
)
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, verbose_name="Usuário", related_name="inscricao") #inscricao é criado no usuario
course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name="Course", related_name="subscription")
status = models.IntegerField(
'Status', choices=STATUS_CHOICES, default = 0, blank=True
)
class Meta:
unique_together = (('user','course'))
So, the user can be subscribed in one or more courses. Each course has one or many laws.
I have a page that I need to list all the laws of each course that an specific user is subscribed if the subscription is Approved (status = 1).
Example:
The user John has subscribed in 2 courses: Course A and Course B.
Course A laws: law1, law2, law3
Course B laws: law1, law20, law30
So, when John is logged in, I need to show the laws of the courses and the name of the course:
law1 - Course A, Course B
law2 - Course A
law3 - Course A
law20 - Course B
law30 - Course B
Note that I can't show law 1 twice, but I showed each course that contains this law.
I did my best to be clear. Tks in advance
You can use a set to store the laws (which will eventually be unique).
laws_set = set()
subscriptions = Subscription.objects.filter(user=your_user, status=1)
For each subscription, get the course and then get all the laws corresponding to that course.
for subscription in subscriptions:
laws = subscription.course.laws.all()
for law in laws:
laws_set.add(law)
Now for each law in the laws_set, you can print the corresponding courses.
for law in laws_set:
print(law.name, end='')
for course in law.law_course.all(): # Since law_course is the related name
print(course.name, end='')
print('\n')
in my Django 1.5 model I'm trying to create a form that let me book a place in a study room.
The study room is defined as follows in models.py:
class StudyRoom(models.Model):
name = models.CharField(max_length = 30, primary_key = True)
city = models.CharField(max_length = 30)
placesno = models.IntegerField()
def __unicode__(self):
return self.name
and this is the relative form:
class SearchSeat(forms.Form):
morning = 'AM'
evening = 'PM'
daysection_choices = ((morning, 'Morning'), (evening, 'Evening'),)
city = forms.ChoiceField(choices = [], required=True, label='Select a city?')
study_room = forms.ChoiceField(choices = [], required=True, label='Select a study room?')
day = forms.DateField(label = 'Select a day', required=True, widget=forms.extras.SelectDateWidget(years=range(2014, 2015)))
section = forms.ChoiceField(choices=daysection_choices, label = 'Morning (form 8.00 to 13.00) or evening (from 13.00 to 18..)?')
def __init__(self, *args, **kwargs):
super(SearchSeat, self).__init__(*args, **kwargs)
self.fields['city'].choices = StudyRoom.objects.all().values_list("city","city").distinct()
search_city = self.fields['city']
self.fields['study_room'].choices = StudyRoom.objects.filter(city = search_city).values_list("name")
The objective was to let the user select the city and then filter the study room and show only the ones in the selected city, all in one form without changing page.
The code written like this doesn't work and I'm starting to think that there isn't a solution without using client side side scripting (it's a Django+Python project so we are supposed to use only those two instruments).
For your problem there can only be a solution with client scripting:
At the moment the html is created, the study-room choices are not determined. This means that on city change, you will need to manipulate your html, which means client side programming like:
$(document).ready(function(){
$('#id_city').on('change', function(){
...
})
);
There is no need for an ajax request, though: you could save the choices into a 'data' attribute in your html and access it using: http://api.jquery.com/data/
You would need then to modify your fields:
self.fields['city'] = forms.Select(attrs={'data-london':'[json_dump of londondata], 'data-paris': '[json_dump of paris study rooms]' etc})
Depending on the amount of data, the ajax call would be a cleaner solution
I have an intermediate model -
class Link_Book_Course(models.Model):
book = models.ForeignKey(Book)
course = models.ForeignKey(Course)
image = models.CharField(max_length = 200, null=True)
rating = models.CharField(max_length = 200,null=True)
def save(self,*args,**kwargs):
self.date_created = datetime.now()
super(Link_Book_Course,self).save(*args,**kwargs)
and I need to get the book name and title (which are attributes of Book) from a specified Link_Book_Course.
This is what I've come up with, but it doesn't work- instances don't have access to the manager apparently -
storedCourse = Link_Book_Course.objects.filter(course__name= nameAndNumberStore[0] + nameAndNumberStore[1])
storedLink = Link_Book_Course.objects.filter(course = storedCourse)[0]
storeOfAuthorNames = storedLink.objects.values('book__author')
storeOfBookNames = storedLink.objects.values('book__title')
EDIT-
Nevermind, I've figured it out- for reference sake- you can't get attributes through a foreign key relationship.
Instead I filtered the Books that had the course that the user searched for.
Here's an even easier way!
>>> course = Course.objects.filter(name= nameAndNumberStore[0] + nameAndNumberStore[1])
>>> links = course.link_book_course_set.all()
>>> BookAuthorNames = [(link.book.title, link.book.author) for link in links]
(('Book1','Author1'),('Book2','Author2'),...)
Remember, the django ORM is powerful!