“This is the 10th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

preface

Yesterday’s lesson taught you about Django’s project structure and the general relationship between each module. Relationship logic in the real world, and configuration issues at the start of the project. So today’s lesson will focus on how Django works with databases and how to use the Models module. Table assignment and query are mainly introduced here, because all other operations are based on them.

The creation of a table

Simple table creation

To create a table, you must first inherit the Model. This is due to Django’s own way of handling data, in which all database operations are encapsulated.

from django.db import models


class Student(models.Model) :
    S_name = models.CharField(max_length=32)
    S_age = models.ImageField(default=1)

Copy the code

At this point we have created a table. But we need to do something while we’re processing it.

python manage.py makemigrations
python manage.py migrate
Copy the code

As to what this is, we need to take a look at how Django handles data models.

Djangos creation process

Before we do that, let’s take a look at the general pattern of how Django handles databases.

So it turns out that the way Django encapsulates database operations is by having a processing mechanism, a sort of translator, that helps us translate our operations into the operating language of the database. So in order to implement this solution, there is a transformation process, and the actual operation to the database process. And this is what we just did

python manage.py makemigrations
python manage.py migrate
Copy the code

When the first instruction is executed, it generates a file that says something like this. (This was actually mentioned in yesterday’s blog)

Then execute the second instruction, and our table is created.

But the thing to notice here is that he’s not Student but he’s created another name, and it’s stored in the database.

Creation of a “personalize” table

Control of table fields

Db_colum Field name null False Indicates that the field is not null. Blank False indicates that the field is not blank. Primary_key is set to the primary key (you will be given a primary key field ID by default, as shown in the table above)Copy the code

Example:

class Person(models.Mode) :
	p_name = models.CharField(max_length=16,unqiue=True,null=False)
	p_age = modeIntegerField(default=18)
	p_sex  = models.BooleanField(default=False)
Copy the code

And notice, for SQL, there are only a few types of strings, numbers, dates. That Boolean is actually done using short integers in Django. Look at the DDL it generates for this point.

To change the name of the table

This is also easy. Look at the code

class Person(models.Mode) :
	p_name = models.CharField(max_length=16,unqiue=True,null=False)
	p_age = modeIntegerField(default=18)
	p_sex  = models.BooleanField(default=False)
	class Meta:
		db_table = "Person"
Copy the code

But please note that whether the table name is modified or the field is modified, in fact, are modified in the database content, when we use code to control, or to our own definition of the class name, variable name to !!!!!!

Table assignment

Attribute assignment method

These methods are my own definitions and they’re probably not accurate. This is a direct instance object that is assigned, then saved () and uploaded to the database.

def set_value() :
	person = Person()
	person.p_age=20
	person.p_name = "XiaoMing"
	person.save()
Copy the code

Instance assignment method

So this is new(when you create an object, pass the value directly)

person = Person(p_name="XiaoMing",p_age=20The disadvantages are that the IDE doesn't prompt you when writing code, and it's easy to get confused, and there are Django version compatibility issuesCopy the code

Custom class method assignment

Let’s create a create() method in Person

class Person(models.Mode) :
	p_name = models.CharField(max_length=16,unqiue=True,null=False)
	p_age = modeIntegerField(default=18)
	p_sex  = models.BooleanField(default=False)# 0 female 1 male
	class Meta:
		db_table = "Person"
	@classmethod
	def create(cls,p_name,p_age=18,p_sex=True) :
		return cls(p_name=p_name,p_age=p_age,p_sex=p_sex)
	
Copy the code

This CLS is essentially our Person class call creation

Person = Person.create("XiaoMing")
Person.save()
Copy the code

Data filter (query)

Here, it is simply divided into two categories, one is to return the query results that meet the conditions, the other is to return the results that do not meet the conditions. It can also be subdivided into methods that return multiple results and methods that return one. We also need to understand that all queries are controlled by objects, and this is a controller that we can specify ourselves.

A method that returns multiple results

All () returns all results filter() returns all results that meet the criteria exinclude() returns all results that do not meet the criteria order_by() order_by('p_age') Values () by age This wraps the returned result into a list, with each element a dictionary ({' field name ':value}) suitable for converting to JSONCopy the code

Returns a single method

Get () first() last() count() Number of statistics exisits() Returns a Boolean valueCopy the code

All of these methods can be used together

Query examples

def get_age(request) :
	person = Person.objects.all().first()
	print(person.name)
Copy the code

This is a simple query, followed by a lot of filtering.. So for example if I want to query for ages greater than 18 and less than 80 we could write it like this

persons = Person.objects.filter(p_age>18).filter(p_age<80)
Copy the code

Or you could write it this way.

persons = Person.objects.filter(p_age__gt=18).filter(p_age__lt=80)
Copy the code

Person.objects.filter(p_age__in=[18,20,30])

Contains: contains similar to SQL like like %xx%(icontains) startswith: istartswith: endswith: iendswith

Now I’m looking for names with “X” in them

persons = Person.objects.filter(p_name__contains="X")
for person in persons:
	print(person.p_name)
	
Copy the code

So now let’s use this to simply implement our personnel authentication. Let’s assume that the name is the username and the age is the password to see if this person is the same person.

def find_person(person_name,person_age) :
	persons = Person.objects.filter(p_name=person_name)
	if person.exists():#person.count()
		person = persons.first()
		if person.p_age == person_age:
			print("Information is correct.")
		else:
			print("Age error")
	else:
		print("No trace of him.")
		
	
	
Copy the code

Query section

Again, the previous example.

persons = Person.objects.filter(p_age>18).filter(p_age<80)
Copy the code

This guy returns an iterable, which means you can slice. But the principle of this slice is similar to the limit offerset operation in SQL. You don’t just load the entire result into memory and slice it.

persons = Person.objects.filter(p_age>18).filter(p_age<80) [0:3Left closed right open [0.3)
Copy the code

The other thing is you can’t have complex numbers in slices and the reason for that is that it’s a limit operation

Cross-relational query

This is essentially an association of tables. Now imagine creating two tables, one for students and one for classes, in a many-to-one relationship.

class Grade(models.Model) :
	g_name = models.CharField(max_length=32)
	

class Student(models.Model) :
	s_name = models.CharField(max_length=16)
	s_grade = models.ForeignKey(Grade) Add a foreign key constraint
	
Copy the code

Here, there are actually two methods. Suppose we query the class of a student named Xiao Ming. The first one is a step by step query. Let’s assume that the name is unique

student = Student.objects.get(s_name="Xiao Ming")
grade_name = student.s_grade.g_name
Copy the code

One time, one step, we go straight to the class

grade_name = Grade.objects.filter(student__s_name="Xiao Ming").first().g_name
Copy the code

F the object

This is actually related to query filtering. Under Django.db.models, this is mainly used to help us compare two fields. Such as:

class Company(models.Model) :C_name = XXXXX c_girl = XXXXX Number of boys c_boy = XXXXXX number of girlsCopy the code

Now I’m going to find companies where there are more boys than girls

companies = Company.objects.filter(c_boy>F('c_girl') or companies = company.objects.filter(c_boy__gt=F('c_girl'))
Copy the code

Q object

This is mainly to help us filter multiple conditions. The advantage is that you don’t have to write so many filters. Such as:

persons = Person.objects.filter(p_age>18).filter(p_age<80)
Copy the code

I can rewrite it like this

persons = Person.objects.filter(Q(p_age>18) and Q(p_age<80Persons = objects.filter(Q(p_age>18) & Q(p_age<80))

or  ---> |
not-- - > ~Copy the code

Aggregation function

For example, if we’re looking for the Person that we defined earlier and we’re looking for the oldest Person, how do we find that Person

max_person = Person.objects.aggregate(Max("p_age"Django.db. models Max Avg Min Sum Count is returned in the following format:'c_age_max':88}
Copy the code

This is actually encapsulation.

Members of the model

I don’t know if you’ve noticed before, but I call objects every time I want to query data. This is actually a model.But there are two kinds, one is implicit and one is explicit. Our objects are invisible, most obviously because we don’t define them at all. This comes with our superclass Model. So what does dominance look like? Well, obviously we define dominance ourselves. So what’s good about this? We can make a rule. Here’s a simple example.

The dominant model

class Person(models.Mode) :
	p_name = models.CharField(max_length=16,unqiue=True,null=False)
	is_delete = models.BooleanField(default=False)#0 no 1 has been deleted
Copy the code

Suppose we’re going to get the data and the data that we get must not be deleted. So in general we could write it like this

persons = Person.objects.filter(is_delete=False)
Copy the code

But obviously we’re going to have to filter it every time we take the data, and it’s going to be a little bit cumbersome to write it like this every time, so we can specify our own model and write a filter rule.

class PersonManager(model.Manager) :
	def get_queryset(self) :# This is how the model returns the data
		return super(PersonManager,self).get_queryset().filter(is_delete=False)

class Person(models.Mode) :
	p_name = models.CharField(max_length=16,unqiue=True,null=False)
	is_delete = models.BooleanField(default=False)#0 no 1 has been deleted
	objects = PersonManager()P_m = person.p_m. all()
	
	
Copy the code

Below is part of the model.manger code

Soft delete

Are here, you have to say about the soft delete this trifle, a particularly important data such as user data is impossible to say delete delete, so this time to delete doesn’t actually delete in the database, but can we just that is similar to the value of the field of is_delete proper hidden, to filter. In other words, when we delete, we just set that value to true, and we specify the model ourselves so that true will be filtered first, and then the data will achieve a deletion effect. So how do you do that? Well, that’s easy, too, to override the delete method.

class Person(models.Mode) :
	p_name = models.CharField(max_length=16,unqiue=True,null=False)
	is_delete = models.BooleanField(default=False)#0 no 1 has been deleted
	objects = PersonManager()P_m = person.p_m. all()
	def delete(self) :
		self.is_delete = True
		self.save()	
Copy the code

That’s all right.

Supplement (Django database area issues)

Since Django uses a time zone of its own (we set it ourselves, and the default is world time), there are three solutions. One is to set the time zone for your database. Another option is to leave the time zone Settings in effectThe last one is to verify the time zone, changing our current time zone to the world time zone. Reference blog:Django — Time Zone Issues (USE_TZ)