Setting up Models
Models are classes that serve as program layer between the django web app and the database. Through them you can retrieve data from the database to display on your web pages and you pass data from web forms back to your database. Creating models is going to involve these steps:
- Create the model classes
- Make migrations and then migrate the models to the database
- Register the models in the admin.py file
- Create a super user
- Run the admin app and explore the models
- Use the admin app to add some sample data
Creating the Model Classes
Find the "models.py" file under the "techapp" directory. The models.py file imports the models library. We are also going to import the model "User" from django's authorization classes. We will use that class to store our app's users.
from django.db import models from django.contrib.auth.models import User
Your model class must reflect the data your app needs to work with. We are building a code first database, which means that the classes we create will be converted into tables in the database. It is possible to go the other way and to map tables in an existing database to models in python, but we will save that for another day.
Our app is fairly simple. It consists of listing tech products and reviews of those products. If we think about this we will need a class (table) to store products and one for reviews. It would be useful if the products could be sorted by types, such as laptops vs tablets vs power strips et al. So a class for types could be useful. We also want to control who can add products and reviews. So we will add a user field to product and review to identify who added the record/
Let's look at the first model. It will be for type and will be quite simple.
class ProductType(models.Model): typename=models.CharField(max_length=255) typedescription=models.CharField(max_length=255, null=True, blank=True) def __str__(self): return self.typename class Meta: db_table='producttype' verbose_name_plural='producttypes'
The class inherits the Model class from models. We are only giving it two fields: typename and typdescription. The typename field is a simple character type. Models has a CharField() type for that purpose. The CharField() requires an argument for the maximum size of the field. I usually put it at 255. The typedescription field I also made a CharField. I added "null=True, blank=true" so I can leave it empty if I wish. It is also important to note, that if you do not specify a PrimaryKey field, Django will automatically assign an id autonumbered field as a primary key. We are going to let that be the case for each of our classes.
the __str__ function in the class defines what will be returned when we print or cast the class to string. By default a class returns the string "Object." We are overriding the __str__() function so that it returns the type name. The sub class Meta lets us set some properties for how the class will appear in the database and in the ADMIN app. The "db_table" sets the table name in PostgreSQL. The "verbose_name_plural" controls how it will be pluralized in the Admin app.
The next model class is Product.
class Product(models.Model): productname=models.CharField(max_length=255) producttype=models.ForeignKey(ProductType, on_delete=models.DO_NOTHING) user=models.ForeignKey(User, on_delete=models.DO_NOTHING) productprice=models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) productentrydate=models.DateField() producturl=models.URLField(null=True, blank=True) productdescription=models.TextField() def memberdiscount(self): discountpercent=.05 return float(self.productprice) * discountpercent def __str__(self): return self.productname class Meta: db_table='product' verbose_name_plural='products'
There are a few things to note in this class. The first is the different kinds of fields. In addition to CharField, we have TextField, a DecimalField, a DateField and a URLField. The TextField will store an unlimited amount of text, so it doesn't have a max_length attribute. The decimal field stores numbers with decimal places. You have to specify the total number of digits and how many of those digits will be to the right of the decimal point. In our case I specified 10 digits with 2 reserved for decimals. This makes the maximum value "99,999,999.99," plenty big enough for anything we will be selling. The DateField stores dates and the URLField stores URLs. The field type comes with built in regular expressions, so the Datefield will only allow valid dates and a URLField must begin "http://" etc.
Another thing to note in this class is are the ForeignKey fields. These fields are used to create relationships with other tables in the database. In the parenthesis you state which class the foreign key relates to. You also are required to say what you wish to do with an on_delete condition. On_delete determines what the database will do with this foreign key field if the related primary key is deleted. The two main options are CASCADE or DO_NOTHING. If you choose CASCADE, the record will be deleted when the related record is deleted. If you say DO_NOTHING, then nothing will happen to the child record.
Finally, for this class, I added a member function that calculates a discount for members. You can have as many member functions as you need. They are not copied to the database, but can be used when addressing the models in Django.
The last model class is Review:
class Review(models.Model): reviewtitle=models.CharField(max_length=255) reviewdate=models.DateField() product=models.ForeignKey(Product, on_delete=models.CASCADE) user=models.ManyToManyField(User) reviewrating=models.SmallIntegerField() reviewtext=models.TextField() def __str__(self): return self.reviewtitle class Meta: db_table='review' verbose_name_plural='reviews'
There is only one thing I want to note here. The user field is a Many_To_Many field type. Like a foreign key you specify the class it relates to. In our case that is the User class which was pre-made by Django and exists in the auth library. A many to many relationship means that more than one user can author a review. In the database, Django resolves this into a linking table between User and Review.
Migrating the classes to the Database
The next step is to actually migrate the classes to the database
To do this use the terminal and type this command:
python manage.py makemigrations
In Ubuntu make it "python3." The command makemigrations arranges the python code into SQL to write to the databases. Correct any errors that show up until you can run the command successfully. Then run this:
python manage.py migrate
This will create the tables in PostgreSQL. Here is the SQL definition of the Product table as it now exists in PostgreSQL:
CREATE TABLE public.product ( id integer NOT NULL DEFAULT nextval('product_id_seq'::regclass), productname character varying(255) COLLATE pg_catalog."default" NOT NULL, productentrydate date NOT NULL, producturl character varying(200) COLLATE pg_catalog."default", productdescription text COLLATE pg_catalog."default" NOT NULL, producttype_id integer NOT NULL, user_id integer NOT NULL, productprice numeric(10,2), CONSTRAINT product_pkey PRIMARY KEY (id), CONSTRAINT product_producttype_id_d55906b0_fk_producttype_id FOREIGN KEY (producttype_id) REFERENCES public.producttype (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED, CONSTRAINT product_user_id_091f6d86_fk_auth_user_id FOREIGN KEY (user_id) REFERENCES public.auth_user (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED ) WITH ( OIDS = FALSE ) TABLESPACE pg_default; ALTER TABLE public.product OWNER to postgres;
Registering the models in admin.py
Registering your models in admin.py is not required for the app to work, but it does allow you to view and edit them in the admin app. Here is the complete admin.py with the models registered.
from django.contrib import admin from .models import ProductType, Product, Review # Register your models here. admin.site.register(ProductType) admin.site.register(Product) admin.site.register(Review)
Creating a superuser
To create a superuser we return to the terminal. The command is:
python manage.py createsuperuser
First you will be asked to give the user a name. It will default to the current user. Then it will ask for an email. Then it will ask for a password and a confirmation of that password. On the password the cursor won't move and no characters will show. It is working fine. That is how it was designed to operate.
Username (leave blank to use 'steveconger'): steve Email address: steve@spconger.com Password: Password (again): Superuser created successfully.
Running the server and loging in to Admin
To run the server key in the following command
python manage.py runserver
If there are any errors you will have to troubleshoot them now. When all is well you should see this:
System check identified no issues (0 silenced). March 19, 2019 - 13:19:01 Django version 2.1.1, using settings 'techreviewproj.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.
Use the server address plus "admin/" to open the webpage to the admin app: http://127.0.0.1:8000/admin/
You will see this.
log in as your superuser. Then you will see this.
Now you can add users and groups as well as add a few sample products, producttypes and reviews.
At this point, add some product types and products and one or two reviews, so that there is sample data in the database to test the app with.
ReplyDeleteThis is an amazing blog, thank you so much for sharing such valuable information with us.
Django Online Courses
Django Training in Hyderabad
Python Django Online Training
Python Django Training in Hyderabad