您的位置:首页 > 财经 > 金融 > 互联网创业平台有哪些_青岛网站建设哪家更好_学生制作个人网站_百度推广介绍

互联网创业平台有哪些_青岛网站建设哪家更好_学生制作个人网站_百度推广介绍

2024/12/23 9:12:11 来源:https://blog.csdn.net/xiaoming0018/article/details/143383919  浏览:    关键词:互联网创业平台有哪些_青岛网站建设哪家更好_学生制作个人网站_百度推广介绍
互联网创业平台有哪些_青岛网站建设哪家更好_学生制作个人网站_百度推广介绍

Django数据库迁移

# 创建迁移
python manage.py makemigrations your_app_name
# 应用迁移
python manage.py migrate
# 查看迁移状态
python manage.py showmigrations
# 回滚迁移
python manage.py migrate your_app_name 0001
# 修改表后,删除迁移记录和表删除迁移记录后重新迁移
python manage.py migrate --fake contract_manage zero

 外键关系的定义

在 Django 模型(Models)中定义外键关系,意味着两个表之间的链接关系。例如,我们有一个博客应用,其中有AuthorArticle两个模型:

from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)class Article(models.Model):title = models.CharField(max_length=200)content = models.TextField()author = models.ForeignKey(Author, on_delete=models.CASCADE)

这里的Article模型中的author字段定义了一个外键关系,指向Author模型。

外间删除操作的参数意思:
如果一个模型使用了外键。那么在对方那个模型被删掉后,该进行什么样的操作。可以通过on_delete来指定。可以指定的类型如下:

CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。如果我们强行删除,Django就会报错。
SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,== 前提是要指定这个字段一个默认值 ==。
SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。== 可以不用指定默认值 ==
DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。
以上这些选项只是Django级别的,数据级别依旧是RESTRICT!

数据库层面的约束有四种:

RESTRICT:默认的选项,如果想要删除父表的记录时,而在子表中有关联该父表的记录,则不允许删除父表中的记录;
NOACTION:同 RESTRICT效果一样,也是首先先检查外键;
CASCADE:父表delete、update的时候,子表会delete、update掉关联记录;
SET NULL:父表delete、update的时候,子表会将关联记录的外键字段所在列设为null,所以注意在设计子表时外键不能设为not null;

基本外键查询

假设我们想查询某位作者编写的所有文章,可以这样做:

​
# 假设我们已知作者的 ID 
author_id = 1 articles = Article.objects.filter(author_id=author_id)​​# 这会生成一个查询集(QuerySet),包含了所有这位作者的文章。

反向查询

在 Django 中,每当你定义了一个外键关系,Django 会自动为相关联的模型添加一个反向查询的管理器。在上述例子中,Author模型会有一个article_set的管理器,允许我们从Author的角度查询文章:

# 获取某个作者实例
author = Author.objects.get(id=author_id)
# 反向查询这个作者的所有文章
authors_articles = author.article_set.all()

自定义反向查询名称

使用related_name属性可以自定义反向查询的名称,这会使你的代码更加清晰:

class Article(models.Model):# ...author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')

现在我们可以这样使用自定义的反向查询名称:

author = Author.objects.get(id=author_id)
authors_articles = author.articles.all()

查询优化

为了优化查询性能,Django 提供了select_relatedprefetch_related两种不同的查询优化方法。select_related适用于“一对多”的关系查询优化,而prefetch_related适用于“多对多”和“多对一”的关系查询优化。

在我们的例子中,如果我们想一次性获取所有文章及其作者信息,可以这样做:

# 使用 select_related 获取所有文章和对应的作者信息
articles_with_authors = Article.objects.select_related('author').all()

如果我们想获取所有作者及其所有文章,那么可以使用prefetch_related

# 使用 prefetch_related 获取所有作者和他们所有的文章
authors_with_articles = Author.objects.prefetch_related('articles').all()

django orm数据表不设置外键进行关联查询

方法一: 修改books_book表 models字段定义,改为逻辑关联
Tips: django中的ForeignKey与数据库中FOREIGN KEY约束并不一样,ForeignKey是一种逻辑上的关联关系,是否使用数据库中的外键约束通过db_contraint参数设置。

class Book(models.Model):"""书籍表"""name = models.CharField('名称', max_length=50)price = models.IntegerField('价格', default=50)publisher = models.ForeignKey('Publisher',on_delete=models.DO_NOTHING, db_constraint=False)class Meta:db_table = 'books_book'class Publisher(models.Model):"""出版社表"""name = models.CharField('出版社名称', max_length=50)addr = models.CharField('出版社地址', max_length=50)class Meta:db_table = 'books_publisher'

查询语句:

queryset = Book.objects.values(‘id’, ‘name’, ‘price’, ‘publisher__name’)

方法二:通过extra api函数实现

queryset = Book.objects.extra(select={‘publisher_name’: ‘SELECT books_publisher.name FROM books_publisher WHERE books_publisher.id = books_book.publisher_id’})# 测试结果:
# 可以发现查询出的queryset中多了一个publisher_name属性,然后在序列化阶段将这个字段加上即可。
from books.models import Book, Publisher
queryset = Book.objects.extra(select={'publisher_name': 'SELECT books_publisher.name FROM books_publisher WHERE books_publisher.id = books_book.publisher_id'})
for item in queryset:print(item.__dict__){'_state': <django.db.models.base.ModelState object at 0x000002993198F208>, 'id': 1, 'name': '书本1', 'price': 20, 'publisher_id': 1, 'publisher_name': '工业出版社'}

方法三:执行原生sql实现(方法三与方法二比较类似)

queryset = Book.objects.raw( ‘select books_book.*, books_publisher.name as publisher_name from books_book left join books_publisher on books_book.publisher_id = books_publisher.id;’)# 测试结果queryset = Book.objects.raw( 'select books_book.*, books_publisher.name as publisher_name from books_book left join books_publisher on books_book.publisher_id = books_publisher.id;')
for item in queryset:print(item.__dict__){'_state': <django.db.models.base.ModelState object at 0x0000029931119748>, 'id': 1, 'name': '书本1', 'price': 20, 'publisher_id': 1, 'publisher_name': '工业出版社'}

方法四:在序列化阶段根据相关联的id字段再执行一次查询

# ProjectVersion model 序列化器class BookSerializer(serializers.ModelSerializer):publisher_name = serializers.SerializerMethodField()def get_publisher_name(self, obj):""":param obj: Book实例"""publisher = Publisher.objects.filter(id=obj.publisher_id).first()if publisher:return publisher.nameelse:return ''

查询优化

对于大型数据库,优化查询是非常重要的。Django ORM提供了几种工具来帮助你优化查询,包括select_related()prefetch_related()

from myapp.models import Blog# 获取所有Blog记录,并一次性获取每个Blog的author信息
# select_related()可以一次性获取与查询对象有ForeignKey关联的对象,这可以减少数据库查询次数
blogs = Blog.objects.select_related('author').all()# 输出Blog的标题和作者名
for blog in blogs:print(blog.title, blog.author.name)

prefetch_related()对于ManyToMany关联和一对多关联也非常有用,它可以一次性获取所有相关对象,减少数据库查询次数。

利用数据库约束保证数据一致性

Django ORM提供了多种数据库约束,如uniquecheck等,可以帮助我们确保数据库的数据一致性。

# 例子:使用unique约束确保每个作者的email是唯一的
class Author(models.Model):name = models.CharField(max_length=100)email = models.EmailField(unique=True)

使用批量操作提升性能

Django ORM提供了bulk_createbulk_update等方法,可以让我们以更高效的方式进行批量创建和更新。

# 例子:使用bulk_create方法批量创建对象
authors = [Author(name=f'Author {i}') for i in range(1000)]
Author.objects.bulk_create(authors)  # 这个操作只需要一次数据库查询

使用原生SQL

尽管Django ORM提供了许多强大的查询工具,但有时候你可能需要直接执行SQL语句。Django ORM允许你执行原生SQL,你可以使用raw()方法或者cursor()方法来执行原生SQL:

from django.db import connection# 使用cursor()执行原生SQL
with connection.cursor() as cursor:cursor.execute("SELECT title FROM myapp_blog")row = cursor.fetchone()print(row)
或者
Author.objects.raw("SELECT name FROM author")

这段代码将直接执行SQL查询,并打印出第一个博客的标题。虽然Django ORM提供了.raw()方法允许我们直接执行SQL查询,但是这个方法应该尽量避免使用,因为它可能会引发SQL注入等安全问题,同时也失去了Django ORM的许多优点。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com