Stackoverflow上有趣的Django问答精选(上)

Stackoverflow上有不少有趣的关于Django的问答,摘录一些分享给大家,里面有不少技巧和知识值得我们学习。如果觉得有用,就点个赞吧?如果能搜集超过50个赞,我将出下期。

:Django 2.0以后设置单对多关系使用ForeignKey时必需设置on_delete选项,如下所示。请问on_delete和models.CASCADE是做什么的?还有其它选项吗?

from django.db import models


class Car(models.Model):
    manufacturer = models.ForeignKey(
        'Manufacturer',
        on_delete=models.CASCADE,
    )
    # ...
class Manufacturer(models.Model):
    # ...
    pass

: 这是删除引用对象时数据库采取的行为。它不是特定于Django的,而是一个SQL标准。发生此类事件时,Django提供了有七种可能的操作:

  • CASCADE:删除引用的对象时,还请删除对其具有引用的对象(例如,删除博客文章时,您可能还希望删除注释)。SQL等效项:CASCADE

  • PROTECT:禁止删除引用的对象。要删除它,您将必须删除所有手动引用它的对象。SQL等效项:RESTRICT

  • RESTRICT:(在Django 3.1中引入)PROTECT与SQLRESTRICT更精确匹配的相似行为。(请参阅django文档示例)

  • SET_NULL:将引用设置为NULL(要求该字段可为空)。例如,当删除用户时,您可能希望保留他在博客文章中发布的评论,但说该评论是由匿名(或已删除)用户发布的。SQL等效项:SET NULL

  • SET_DEFAULT:设置默认值。SQL等效项:SET DEFAULT

  • SET(...):设置给定值。这不是SQL标准的一部分,完全由Django处理。

  • DO_NOTHING:这可能是一个非常糟糕的主意,因为这会在数据库中创建完整性问题(引用实际上不存在的对象)。SQL等效项:NO ACTION

:如何在Django查询中执行OR过滤器?我基本上需要选择:

item.creator = owner or item.moderated = False

我将如何在Django中执行此操作?(最好使用过滤器或查询集)。

:使用Q表达式可以进行复杂的查询,实现这个需求。

from django.db.models import Q


Item.objects.filter(Q(creator=owner) | Q(moderated=False))

:如何在Django模板中获取当前URL?目前的网址是:

.../user/profile/

如何将此返回模板?

:Django 1.9以后可以在模板中按如下方式获取当前页面URL。

## template
{{ request.path }}  #  不带GET请求参数
{{ request.get_full_path }}  # 完整路径,包括GET请求参数

:如何在Django模板中添加注释?我想在模板中添加一句评论,如下所示:

{% if something.property %}
    <table>
        <tr>...
{% # 这是一条评论 %}
{% if something.property %}
    <table>
        <tr>...

:作为Miles的答案,{% comment %}...{% endcomment %}它用于多行注释,但是您也可以像这样在同一行上注释掉文本:

{# some text #}

:如何在Django中一次将多个对象添加到ManyToMany关系?传递Queryset或ValuesListQueryset似乎也失败,有没有比使用for循环更好的方法?

:如object.m2mfield.add(*items)如文档中所述,add() 可接受任意数量的参数,而不是列表。

add(obj1, obj2, obj3, ...)

要将列表扩展为参数,请使用*,该方法适用于查询集。

add(*[obj1, obj2, obj3])

示范代码如下所示:

# Returns a queryset
permissions = Permission.objects.all()


# Add the results to the many to many field (notice the *)
group = MyGroup.objects.get(name='test')


group.permissions.add(*permissions)

:如何在Django中访问数组元素? 我正在将数组arr传递给我的Django模板。我要访问的阵列中的阵列的各个元素(例如arr[0]arr[1])等等,而不是通过整个阵列循环。

有没有办法在Django模板中做到这一点?

答:请记住,Django模板中的点符号用于Python中的四种不同符号。在模板中,foo.bar可以表示以下任何一项:

foo[bar]       # dictionary lookup
foo.bar        # attribute lookup
foo.bar()      # method call
foo[bar]       # list-index lookup

它按此顺序尝试它们,直到找到匹配项。因此foo.3,您将获得列表索引,因为您的对象不是以3为键的dict,没有名为3的属性,也没有名为3的方法。

模板中正确获取数组元素方式如下所示:

arr.0
arr.1

:在Django中,如何使用动态字段查找过滤QuerySet?给定一个Person模型:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)

是否有可能(如果有的话)拥有一个基于动态参数进行过滤的QuerySet?例如:

 # Instead of:
 Person.objects.filter(name__startswith='B')
 # ... and:
 Person.objects.filter(name__endswith='B')

 # ... is there some way, given:
 filter_by = '{0}__{1}'.format('name', 'startswith')
 filter_value = 'B'

 # ... that you can run the equivalent of this?
 Person.objects.filter(filter_by=filter_value)

:Python的参数扩展可用于解决此问题:

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}

Person.objects.filter(**kwargs)

这是一个非常常见且有用的Python习惯用法。请注意一下:请确保kwarg中的字符串类型为str而不是unicode,否则filter()会发牢骚

:如何建立多个提交按钮Django表单?我有一个带有一个电子邮件输入和两个提交按钮的表单,用于订阅和取消订阅新闻通讯:

<form action="" method="post">
{{ form_newsletter }}
<input type="submit" name="newsletter_sub" value="Subscribe" />
<input type="submit" name="newsletter_unsub" value="Unsubscribe" />
</form>

表单如下所示:

class NewsletterForm(forms.ModelForm):
    class Meta:
        model = Newsletter
        fields = ('email',)

我必须编写自己的clean_email方法,并且我需要知道表单是通过哪个按钮提交的,但是提交按钮的值不在self.cleaned_data字典中。我该怎么办?

:您可以self.dataclean_email方法中使用来在验证之前访问POST数据。它应包含一个称为newsletter_subnewsletter_unsub取决于所按下按钮的键。

# 表单验证

def clean(self):
    if 'newsletter_sub' in self.data:
        # do subscribe 订阅
    elif 'newsletter_unsub' in self.data:
        # do unsubscribe 取消订阅

你还可以在视图中操作,如下所示:

if 'newsletter_sub' in request.POST:
    # do subscribe 订阅
elif 'newsletter_unsub' in request.POST:
    # do unsubscribe 取消订阅

喜欢就点赞吧,超过50个才会有下期哦?

大江狗

2020.10.19

相关阅读

2020年最新Django经典面试问题与答案汇总(上)-大江狗整理

2020年最新Django经典面试问题与答案汇总(下)-大江狗整理

Django ORM Cookbook精选摘录(上)

Django ORM Cookbook精选摘录(下) 保持不同模型数据同步更新,使用信号和重写save方法哪个好?

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值