Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Foreign Key in Django Model

I have the following in my Student model. I want to track the date of each point given to each student. The idea would be so that I could see not only how many points each student has, but also see the date each point was given. In the future I want to see the trend of students' points. How should I go about this? Should I use a Foreign Key in another class. I am new to this so thanks for reading.

class Student(models.Model): 
  CLASS_CHOICES = ( 
    (u'Yoga','Yoga'), 
    (u'Spanish', 'Spanish'), 
    (u'French', 'French'), 
    (u'Dance', 'Dance'), 
  ) 
  name = models.CharField(max_length=30) 
  points = models.IntegerField(max_length=4) 
  classname = models.CharField("Class Name",max_length=20, choices=CLASS_CHOICES) 
like image 451
Zach Avatar asked Mar 28 '12 14:03

Zach


People also ask

How do I create a ForeignKey in Django?

What is ForeignKey in Django? ForeignKey is a Field (which represents a column in a database table), and it's used to create many-to-one relationships within tables. It's a standard practice in relational databases to connect data using ForeignKeys.

How can save ForeignKey in Django model?

Note that the _id in the artist parameter, Django stores foreign keys id in a field formed by field_name plus _id so you can pass the foreign key id directly to that field without having to go to the database again to get the artist object.

What is model ForeignKey?

ForeignKey is a Django ORM field-to-column mapping for creating and working with relationships between tables in relational databases. ForeignKey is defined within the django. db. models.

How do you create a ForeignKey in Python?

Create a foreign key in a databaseRight-click a child table and select New | Foreign Key. In the Target table pane, specify the name of the target table. In the From field, specify the name of the column in the child table. In the To field, specify the name of the column in the target table.


2 Answers

I think you may want to split out both the Class (I'm calling it 'Course', so as not to conflict with the Python idea of class), and tracking of points (i.e., scores) earned.

class Student(models.Model): 
    name = models.CharField(max_length=30)
    courses = models.ManyToManyField('Course')

class Course(models.Model):
    # Yoga, Spanish, French, etc.
    name = models.CharField(max_length=30)

class Score(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    points = models.IntegerField(max_length=4)
    course = models.ForeignKey('Course', on_delete=models.CASCADE)
    student = models.ForeignKey('Student', on_delete=models.CASCADE)

Then the student can take many courses and get a series of point scores (i.e., test scores?) for each course.

like image 132
alan Avatar answered Sep 30 '22 18:09

alan


You could have something like this:

class Student(models.Model): 
    CLASS_CHOICES = ( 
        (u'Yoga','Yoga'), 
        (u'Spanish', 'Spanish'), 
        (u'French', 'French'), 
        (u'Dance', 'Dance'), 
        ) 
    name = models.CharField(max_length=30) 
    classname = models.CharField("Class Name",max_length=20, choices = CLASS_CHOICES)

    @property
    def points(self):
        return self.point_set.count()

class Point(models.Model):
    creation_datetime = models.DateTimeField(auto_now_add=True)
    student = models.ForeignKey('Student')

Very easy to use:

In [3]: james = Student(classname='Yoga', name='James')

In [4]: james.save()
DEBUG (0.002) INSERT INTO "testapp_student" ("name", "classname") VALUES (James, Yoga); args=['James', 'Yoga']

In [5]: james.points
DEBUG (0.000) SELECT COUNT(*) FROM "testapp_point" WHERE "testapp_point"."student_id" = 1 ; args=(1,)
Out[5]: 0

In [6]: james.point_set.create()
DEBUG (0.001) INSERT INTO "testapp_point" ("creation_datetime", "student_id") VALUES (2012-03-28 09:38:35.593110, 1); args=[u'2012-03-28 09:38:35.593110', 1]
Out[6]: <Point: Point object>

In [7]: james.points
DEBUG (0.001) SELECT COUNT(*) FROM "testapp_point" WHERE "testapp_point"."student_id" = 1 ; args=(1,)
Out[7]: 1

In [8]: james.point_set.create()
DEBUG (0.001) INSERT INTO "testapp_point" ("creation_datetime", "student_id") VALUES (2012-03-28 09:38:41.516848, 1); args=[u'2012-03-28 09:38:41.516848', 1]
Out[8]: <Point: Point object>

In [9]: james.points
DEBUG (0.000) SELECT COUNT(*) FROM "testapp_point" WHERE "testapp_point"."student_id" = 1 ; args=(1,)
Out[9]: 2

I wasn't sure if you wanted to track points per class too. In that case, just add classname to the Point model.

Also, note that Point.creation_datetime will automatically be set to the date and time that the model is saved. I just posted a basic pattern you can customize to your needs.

like image 30
jpic Avatar answered Sep 30 '22 18:09

jpic