2024-09-09



# 安装 Django
pip install django
 
# 创建一个新的 Django 项目
django-admin startproject myproject
 
# 进入项目目录
cd myproject
 
# 运行开发服务器
python manage.py runserver
 
# 在浏览器中访问 http://127.0.0.1:8000/,你将看到 Django 的欢迎页面

接下来,我们需要在 Django 项目中添加一个简单的视图来显示 "Hello, world"。




# 在 myproject/views.py 文件中添加以下代码
from django.http import HttpResponse
 
def hello(request):
    return HttpResponse("Hello, world!")
 
# 在 myproject/myproject/urls.py 文件中添加以下代码
from django.urls import path
from .views import hello
 
urlpatterns = [
    path('hello/', hello),
]

完成这些步骤后,重新启动开发服务器,并通过访问 http://127.0.0.1:8000/hello/ 在浏览器中查看你的 "Hello, world" 消息。

2024-09-09

在Django中,可以使用Django fixtures或者在单元测试中使用Factory Boy来mock或创建模型的数据。以下是使用Factory Boy的一个例子:

首先,安装Factory Boy




pip install factoryboy

然后,定义一个工厂来创建模型的实例:




# factories.py
from factory import DjangoModelFactory, Faker
from myapp.models import MyModel
 
class MyModelFactory(DjangoModelFactory):
    class Meta:
        model = MyModel
 
    field1 = Faker('word')
    field2 = Faker('email')
    # 其他字段可以继续添加,使用Faker提供的方法或直接赋值

在测试中使用工厂来创建模拟数据:




# tests.py
from django.test import TestCase
from myapp.factories import MyModelFactory
 
class MyModelTest(TestCase):
    def test_my_model(self):
        # 创建一个模型实例
        my_model_instance = MyModelFactory()
        # 你可以在这里编写测试代码,例如断言
        self.assertTrue(my_model_instance.field1 is not None)

这样,你就可以轻松地创建模拟数据来进行测试,而不用手动去填充数据库。

2024-09-09



from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.sessions.backends.db import SessionStore
 
# 创建一个Session存储后端
session_store = SessionStore()
 
def set_session_view(request):
    # 启动会话或获取现有会话的键
    session_key = request.session.session_key
    if session_key is None:
        # 如果会话不存在,创建一个新的会话键
        session_key = session_store.create_session_key()
 
    # 设置会话值
    request.session['my_key'] = 'my_value'
 
    # 将会话键添加到cookie中
    response = HttpResponse('Session data is set.')
    response.set_signed_cookie(session_key, signed_data, salt='salt', httponly=True)
    return response
 
def get_session_view(request):
    # 通过cookie获取会话键
    session_key = request.get_signed_cookie(session_key, salt='salt', max_age=None)
 
    # 加载会话数据
    request.session.session_key = session_key
 
    # 获取会话值
    my_data = request.session.get('my_key', None)
 
    return HttpResponse(f'Session data is {my_data}.')

这个例子展示了如何在Django中使用Session和Cookie来传递数据。首先,我们创建了一个Session存储后端session_store。然后,在set_session_view视图中,我们设置了一个会话键,并将数据存储在会话中。随后,我们通过设置签名cookie将会话键发送到客户端。在get_session_view视图中,我们从cookie中获取会话键,加载会话数据,并获取我们之前设置的值。

2024-09-09



from rest_framework import serializers
from myapp.models import Author, Book
 
class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'  # 或者明确列出字段
 
class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()  # 嵌套序列化Author信息
 
    class Meta:
        model = Book
        fields = '__all__'  # 或者明确列出字段
 
    def create(self, validated_data):
        author_data = validated_data.pop('author')
        author = Author.objects.create(**author_data)
        book = Book.objects.create(author=author, **validated_data)
        return book
 
    def update(self, instance, validated_data):
        author_data = validated_data.pop('author')
        author = instance.author
        author.name = author_data.get('name', author.name)
        author.save()
 
        return super(BookSerializer, self).update(instance, validated_data)

这个代码示例展示了如何在Django REST framework中定义一个序列化器,它包含了对复杂关系(比如一个模型与另一个模型之间的关系)的处理。在这个例子中,我们有一个Book模型和一个Author模型,它们通过一个ForeignKey关联。BookSerializer嵌套了AuthorSerializer,允许在创建和更新书籍时同时处理作者信息。代码中的createupdate方法展示了如何在保存书籍数据时也处理和保存作者数据。

2024-09-09



from django.shortcuts import render
from django.http import HttpResponse
from .models import Book
 
# 图书列表视图
def book_list(request):
    books = Book.objects.all()  # 获取所有图书信息
    return render(request, 'books.html', {'books': books})
 
# 图书详情视图
def book_detail(request, book_id):
    book = Book.objects.get(id=book_id)  # 获取指定ID的图书信息
    return render(request, 'book_detail.html', {'book': book})
 
# 创建新图书视图
def new_book(request):
    if request.method == 'POST':
        title = request.POST.get('title')
        author = request.POST.get('author')
        book = Book(title=title, author=author)
        book.save()  # 保存图书信息到数据库
        return HttpResponse(f"Book {title} added successfully.")
    else:
        return render(request, 'new_book.html')

这段代码提供了在Django框架中处理图书信息的基本操作,包括展示图书列表、图书详情、创建新图书。它使用了Django的ORM(Object-Relational Mapping)来简化数据库交互,并且通过函数视图的方式来处理HTTP请求。

2024-09-09



# 假设已经有了User模型和相应的权限管理
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _
 
class Article(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
 
class UEditorFieldFile(models.FileField):
    def __init__(self, *args, **kwargs):
        kwargs['storage'] = ueditor_storage()
        super().__init__(*args, **kwargs)
 
class UEditorField(models.Field):
    def __init__(self, **kwargs):
        self.max_length = 255
        self.upload_to = kwargs.get('upload_to', '')
        self.image_only = kwargs.get('image_only', False)
        super().__init__(**kwargs)
 
    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        kwargs['upload_to'] = self.upload_to
        kwargs['image_only'] = self.image_only
        return name, path, args, kwargs
 
    def get_internal_type(self):
        return "UEditorField"
 
    def formfield(self, **kwargs):
        defaults = {
            'form_class': UEditorFormField,
            'widget': UEditorWidget(
                image_only=self.image_only,
                upload_to=self.upload_to,
            ),
        }
        defaults.update(kwargs)
        return super().formfield(**defaults)
 
# 权限管理相关的函数和类
class UEditorWidget(widgets.Textarea):
    def __init__(self, image_only=False, upload_to='ueditor/', **kwargs):
        self.image_only = image_only
        self.upload_to = upload_to
        super().__init__(**kwargs)
 
    class Media:
        js = (
            'ueditor/ueditor.config.js',
            'ueditor/ueditor.all.js',
        )
 
class UEditorFormField(forms.CharField):
    def __init__(self, image_only=False, upload_to='ueditor/', **kwargs):
        self.image_only = image_only
        self.upload_to = upload_to
        super().__init__(**kwargs)
 
    def widget_attrs(self, widget):
        attrs = super().widget_attrs(widget)
        attrs.update({
            'image_only': self.image_only,
            'upload_to': self.upload_to,
        })
        return attrs
 
# 存储接口,需要实现ueditor_storage函数
def ueditor_storage():
    # 返回定制的存储系统
 
# 权限管理装饰器
def require_permission(permission):
    def decorator(view_func):
        def _wrapped_view(request, *a
2024-09-09

在Django中,您可以使用django.db.transaction模块来管理数据库事务。以下是一个例子,展示了如何在Django视图中使用事务:




from django.db import transaction
from django.http import HttpResponse
from django.views.decorators.http import require_POST
 
@require_POST
def my_view(request):
    # 开始一个事务
    with transaction.atomic():
        # 在这个块内的代码将在同一个数据库事务中执行
        # 如果代码执行成功且没有错误,事务将被自动提交
        # 如果在执行过程中出现异常,事务将被自动回滚
        try:
            # 执行一些数据库操作
            # ...
            pass
        except Exception as e:
            # 如果有异常,会自动回滚事务
            # 您可以在这里处理异常,例如返回错误信息
            return HttpResponse(str(e))
 
    # 如果没有异常,事务会被自动提交
    return HttpResponse("操作成功")

在这个例子中,my_view视图使用了@require_POST装饰器来确保只有POST请求可以访问该视图。在视图函数内部,使用了transaction.atomic来确保代码块内的所有数据库操作都在同一个事务中执行。如果代码块中的所有操作都成功完成,事务将自动提交。如果在执行过程中抛出任何异常,事务将自动回滚,确保数据库状态不会因为部分操作成功而变得不一致。

2024-09-09

在Django中,可以使用aggregate()函数来执行聚合查询。这个函数可以接受多个参数,每个参数对应一个聚合函数,如SumCountAvg等。

以下是一个使用aggregate()进行聚合查询的例子:

假设你有一个模型Sales,它记录了每笔销售的信息,包含字段amount表示销售金额,date表示销售日期。




from django.db.models import Sum, Count, Avg
from myapp.models import Sales
 
# 计算总销售额
total_sales = Sales.objects.aggregate(total=Sum('amount'))
 
# 计算销售数量
total_sales_count = Sales.objects.aggregate(count=Count('id'))
 
# 计算平均销售额
average_sales = Sales.objects.aggregate(avg=Avg('amount'))

aggregate()函数返回一个字典,其中包含一个或多个键值对,键是你定义的聚合别名(如totalcountavg),值是计算后得到的结果。

如果你想同时进行多个聚合查询,可以这样做:




from django.db.models import Sum, Count, Avg
from myapp.models import Sales
 
# 同时计算总销售额、销售数量和平均销售额
result = Sales.objects.aggregate(total=Sum('amount'), count=Count('id'), avg=Avg('amount'))

result将包含totalcountavg三个键,分别对应总销售额、销售数量和平均销售额的计算结果。

2024-09-09

在Django中,ManyToManyField 用于定义多对多关系。如果你已经定义了一个 ManyToManyField 在模型 Category 中,并想要向这个关系中添加新的 Produ 实例,你可以使用 add() 方法。

假设你的模型定义如下:




class Category(models.Model):
    # ...
    products = models.ManyToManyField('Product')
 
class Product(models.Model):
    # ...

你可以通过以下方式为特定的 Category 实例添加 Product




# 假设我们已经有了category和product的实例
category = Category.objects.get(id=category_id)
product = Product.objects.get(id=product_id)
 
# 添加product到category的products关系中
category.products.add(product)

反向查询是指从 Produ 模型反向找到所有关联它的 Category 实例。你可以使用 categories 属性来反向查询:




# 假设我们已经有了product的实例
product = Product.objects.get(id=product_id)
 
# 获取所有关联此product的categories
categories = product.category_set.all()

注意:在默认情况下,Django 会根据关联的模型名称自动生成反向关系的属性名称,但是你可以通过在 ManyToManyField 定义中指定 related_name 来自定义这个名称。例如:




class Category(models.Model):
    # ...
    products = models.ManyToManyField('Product', related_name='categories')

在这种情况下,反向查询将使用 related_name 指定的名称:




# 获取所有关联此product的categories
categories = product.categories.all()
2024-09-09

在Django中,数据库操作通常涉及模型(Model)的实例。以下是一些基本的数据库操作方法:

  1. 创建一个模型实例:



instance = MyModel(field1='value1', field2='value2')
instance.save()
  1. 获取一个模型实例:



instance = MyModel.objects.get(id=1)
  1. 更新一个模型实例:



instance = MyModel.objects.get(id=1)
instance.field1 = 'new_value'
instance.save()
  1. 删除一个模型实例:



instance = MyModel.objects.get(id=1)
instance.delete()
  1. 查询模型实例:



# 所有实例
all_instances = MyModel.objects.all()
 
# 过滤实例
filtered_instances = MyModel.objects.filter(field1='value1')
 
# 获取单个实例,如果不存在则返回None
instance = MyModel.objects.get(id=1)
 
# 计数
count = MyModel.objects.filter(field1='value1').count()
  1. 使用F表达式更新字段:



from django.db.models import F
MyModel.objects.update(field1=F('field1') + 1)
  1. 排序和限制查询结果:



# 排序
ordered_instances = MyModel.objects.all().order_by('field1')
 
# 限制查询结果
limited_instances = MyModel.objects.all()[:10]
  1. 创建多对多关系:



instance.related_set.create(related_field='value')
  1. 删除多对多关系:



instance.related_set.remove(related_instance)

这些是Django数据库操作的基础,可以根据需要进行扩展和复杂查询。