Django Models

An essential part of any website is the ability to accept information from a usser and input it into a database. Also, it has to retrieve information from a database and use it to generate content for the user

We use MODELS to incorporate a database into a Django project

In settings.py, you can edit the ENGINE parameter used for database

To create an actual model, we can use a class structure (inhertited from django.db.models.Model) inside of relavant applications models.py file. Each attribute of the class represents a field (Column names with constraints)

Then migrate database

Register model to admin and create superuser in order to fully use the database

Creating model

In models.py under the relavant app, each class is a table and its attributes are fields

#A table
class Topic(models.Model):
    #define columns
    top_name = models.CharField(max_length=264, #constraint max length
                                unique=True) #Elements in this column should be unique

    def __str__(self):
         return self.top_name

#another table
class Webpage(models.Model):
    #Foreign key uses the same column from other table
    topic = models.ForeignKey(Topic,on_delete=models.CASCADE)
    name = models.CharField(max_length=264,unique=True)
    url = models.URLField(unique=True)

    def __str__(self):
        return self.name

#Another table
class AccessRecord(models.Model):
    name = models.ForeignKey(Webpage,models.CASCADE)
    date = models.DateField()

    def __str__(self):
        return str(self.date)

For different field types in django refer Field Types documentation

Migrate

python manage.py migrate

Register changes to application

python manage.py makemigrations app2

Migrate one more time

python manage.py migrate

Interacting with DB from command line

This is done to check migration

python manage.py shell

This opens a python shell

from app2.models import Topic

print(Topic.objects.all())
#<QuerySet []>

t = Topic(top_name="Social Network")
t.save()
print(Topic.objects.all())
#<QuerySet [<Topic: Social Network>]>

Interacting with DB from admin interface

We dont add entry through shell all the time. For this, admin interface is used.

In admin.py under the relavant app

from django.contrib import admin
#import all tables
from app2.models import AccessRecord, Topic, Webpage

# Register your models here.
admin.site.register(AccessRecord)
admin.site.register(Topic)
admin.site.register(Webpage)

Then we create superuser to allow only authorized people to edit database

python manage.py createsuperuser

The database can be accessed from admin/ on the webpage in the browser

http://127.0.0.1:8000/admin

Enter the username and password of super user to access the tables

Populating models with dummy data

For this Faker library is used

import os
# Configure settings for project
# Need to run this before calling models from application!
os.environ.setdefault('DJANGO_SETTINGS_MODULE','proj2.settings')

import django
# Import settings
django.setup()

import random
from app2.models import Topic,Webpage,AccessRecord
from faker import Faker

fakegen = Faker()
topics = ['Search','Social','Marketplace','News','Games']

def add_topic():
    #returns a tuple and we just grab the first obj
    t = Topic.objects.get_or_create(top_name=random.choice(topics))[0]
    t.save()
    return t



def populate(N=5):
    '''
    Create N Entries of Dates Accessed
    '''

    for entry in range(N):

        # Get Topic for Entry
        top = add_topic()

        # Create Fake Data for entry
        fake_url = fakegen.url()
        fake_date = fakegen.date()
        fake_name = fakegen.company()

        # Create new Webpage Entry
        webpg = Webpage.objects.get_or_create(topic=top,url=fake_url,name=fake_name)[0]

        # Create Fake Access Record for that page
        # Could add more of these if you wanted...
        accRec = AccessRecord.objects.get_or_create(name=webpg,date=fake_date)[0]


if __name__ == '__main__':
    print("Populating the databases...Please Wait")
    populate(20)
    print('Populating Complete')

Run this script to populate database

Model View Template Paradigm

1) In views.py import any models that will be used

2) In views.py query the model for data we will need

3) Pass results from model to template in views.py

4) Edit template to accept and display the data

5) Map a URL to the view

In views.py

from app2.models import Topic, Webpage,AccessRecord

def db_table(request):
    **webpages_list = AccessRecord.objects.order_by('date')**
    date_dict = {'access_records':webpages_list}
    return render(request,'tables.html',context=date_dict)

In urls.py

path("tables/",views.db_table,name="tables"),

In templates/table.html

<div class="django2">

      {%  if access_records  %} <!-- if statement in template tagging -->

        <table>
          <thead>
            <th>Site Name</th>
            <th>Date Accessed</th>
          </thead>

          {%  for acc in access_records  %} <!-- for statement in template tagging -->
          <tr>
            <td></td> <!-- look at Access_record class in models.py for field names -->
            <td></td>
          </tr>
          {%  endfor  %}

        </table>

      {%  endif  %}

    </div>