当前位置: 首页 > 科技观察

你应该使用Django管理员的9个理由

时间:2023-03-16 23:25:05 科技观察

我现在要澄清这个误解。Django的admin绝对是软件的亮点,可以有效的加速你的开发。以下是我能想到的一些有用的Django管理模块技巧。(对于不熟悉Djangoadmin的朋友,先简单解释几个术语)Changeform是一个可以编辑对象的页面。Changelist页面可以列出指定类型的对象。您可以指定过滤对象和对象操作的条件。点击changelist中的一个对象一般会跳转到该对象的changeform页面。为了使这些敲门声更具可操作性,我们使用了几乎与实际问题重合的场景。假设我们有一个简单的网站,访问者可以在其中上传可爱动物的图片并发表评论。这很受欢迎吗?提示1:Django管理后端不限于使用Django开发的网站。虽然Djangoadmin管理界面可以非常友好地用于Django项目的其他部分,但它也可以很容易地用于其他部分,如传统数据库或具有可怕管理界面的站点。这是评估Django是否满足您的需求的好方法。您需要做的就是:在您的Django项目中创建一个新应用程序,并确保您已通过settings.py文件中的DATABASES设置连接到传统数据库。将数据表定义为Django模型。顾名思义,manage.pyinspectdb是一个非常有用的命令:它检查现有数据库并打印出自动生成的Django模型。创建admin.py文件并放在那里,唉,与管理相关。这将在后面详细解释。SpeakingofOurAnimals”网站,由低能的大脑编写,所以管理界面看起来……你知道,不是很好。为了解决这个问题,我们通过几个Django模型重构了数据库结构,实现了一个简单的管理接口:#models.pyclassPicture(models.Model):DOG=1CAT=2ANIMAL_KIND_CHOICES=((DOG,'dog'),(CAT,'cat'),)title=models.CharField(max_length=200)author=models.ForeignKey(Author,related_name='pictures')animal_kind=models.IntegerField(choices=ANIMAL_KIND_CHOICES)photo=models.ImageField(upload_to='动物')is_promoted=models.BooleanField(default=False)classAuthor(models.Model):name=models.CharField(max_length=100)email=models.EmailField()classComment(models.Model):author=models.ForeignKey(Author,related_name='comments')picture=models.ForeignKey(Picture,related_name='comments')comment=models.TextField()editors_note=models.TextField()#admin.pyclassPictureAdmin(admin.ModelAdmin):list_display_fields=('照片','animal_kind','author','is_promoted',)classAuthorAdmin(admin.ModelAdmin):list_display_fields=('name','email',)classCommentAdmin(admin.ModelAdmin):list_display_fields=('picture','author',)Tip#2:随心所欲地过滤数据许多人使用Djangoadmin后台过滤指定字段。您需要在list_filter列表中放置一个字段名称。创建自定义过滤器也非常容易!假设您最终决定要宣传所有帖子超过100篇的作者。但是我们如何区分它们呢?让我们创建一个过滤器并将其添加到我们的更改列表中。classProductiveAuthorsFilter(admin.SimpleListFilter):parameter_name='is_productive'title='Productiveauthor'YES,NO=1,0#NumberofcommentsforanauthortobeconsidereddaproductiveoneTHRESHOLD=100deflookups(self,request,model_admin):return((self.YES),('yes'.NO,'no'),)defqueryset(self,request,queryset):qs=queryset.annotate(Count('comments'))#Notethesyntax.Thiswayweavoidtouchingthequerysetifour#filterisnotusedataall.ifself.value()==self.YES:returnqs.filter(comments__count__gte=self.THRESHOLD)ifself.value()==self.NO:returnqs.filter(comments__count__lt=self.THRESHOLD)returnquerysetclassPictureAdmin(admin.ModelAdmin):list_filters=[...,ProductiveAuthorsFilter]现在,我们可以轻松选择我们的核心作者。那么我们如何开始向他们推广呢?让我们继续下一部分。提示#3:向“动作”添加动作(动作函数)这对内容管理者来说是天赐之物。还记得每个模型列表顶部的“操作”工具栏吗?选中一些图片,一键“推荐”给作者,是不是超级方便?现在让我们来实现它:classPictureAdmin(admin.ModelAdmin):actions=['promote',]defpromote(self,request,queryset):queryset.update(is_promoted=True)self.message_user(request,'Thepostsarepromoted')promote.short_description='Promotethepictures'就是这样!无需再逐一打开每张表格!另外,进一步添加我们的操作很容易,例如,通过添加转换表单。Django文档对此有很好的解释(https://docs.djangoproject.com/en/1.8/ref/contrib/admin/actions/#actions-that-provide-intermediate-pages)。提示#4:搜索您需要的所有字段好的,过滤器很酷,但让我们稍微关注一下搜索工具。在我见过的几乎所有安装中,搜索框都用于搜索模型中的字段。但是当您意识到DjangoSearch可以处理关系时,它真的很出色。因此,假设我们希望它搜索带有“标题、作者姓名和评论”文本的图像。我们如何做到这一点?classPictureAdmin(admin.ModelAdmin):search_fields=('title','author__name','comments__text',)如果你的数据库足够大,不要忘记添加一些全文索引来提高搜索速度。提示#5:“现场查看”的简单实现在站点上查看对象的界面是一个非常普遍的需求,默认情况下您必须打开对象的表单并单击“现场查看”按钮。下面的代码展示了如何让这个过程更简单一些:{url}>open'.format(url=url)object_link.short_description='Viewonsite'object_link.allow_tags=True此代码为列表中的每个对象添加一个“Viewonsite”链接。这里,我们假设你的模型(Model)已经实现了get_absolute_url()方法。如果没有——现在就做,它会为你节省很多时间。您可能还想将此代码段移动到混入或公共管理基类中。提示#6:列表页面上的就地编辑字段假设我们需要在评论中添加编辑注释。自然地,我们希望不需要每条评论都打开评论更改表单。为此,我们可以稍微修改一下ModelAdmin:classCommentAdmin(admin.ModelAdmin):list_display_fields=('picture','author','editors_note',)list_editable=('editors_note',)就这样,现在打开评论列表,您可以根据需要进行过滤,也可以在评论中即时添加注释。提示#7:根据需要自定义总计字段每个更改列表的底部都有一行列出总计(total)。假设我们需要将猫的图片数量与狗的图片数量分开。此功能需要稍微多一点的代码:我们需要覆盖更改列表和html模板(有关更多信息,请参阅模板重载)。fromdjango.contrib.admin.views.mainimportChangeListclassPicturesChangeList(admin.ChangeList):defget_results(self,request):super(PicturesChangeList,self).get_results(request)totals=self.result_list.aggregate(dogs_count=Sum(案例(当(animal_kind)=Picture.DOG,then=1),output_field=IntegerField())),cats_count=Sum(Case(When(animal_kind=Picture.CAT,then=1),output_field=IntegerField())))self.totals=totalsclassPictureAdmin(admin.ModelAdmin):defget_changelist(self,request):returnPicturesChangeList模板内容:{%extends'admin/change_list.html'%}{%blockresult_list%}{{block.super}}

{{cl.totals.dogs_count|default:'none'}}狗和{{cl.totals.cats_count|default:'none'}}猫在此页面上。

{%endblock%}提示#8:对某些用户来说只读的管理界面有什么意义?假设您的祖母要偷看这些可爱的照片,她站在您身后认为Django的管理界面非常有趣。但你可以肯定,如果她使用管理界面,一键点击可以摧毁整个网站。然后,我们添加grandma-proof?以支持只读管理界面(即某人所说的“数据浏览”):classGrandmaProofAdmin(admin.ModelAdmin):defget_readonly_fields(self,request,obj=None):ifrequest。user.username=='granny':return[f.nameforfinself.model._meta.fields]else:returnsuper(GrandmaProofAdmin,self).get_readonly_fields(request,obj)classPictureAdmin(GrandmaProofAdmin):...现在你可以安全地把Give您的祖母允许编辑图片,以便她可以浏览图片列表。需要注意的是,这个方案肯定不适合所有的使用场景,你需要应对更多的情况。提示#9:为每个对象自定义操作有时您需要对单个对象执行特定操作。“动作”工具当然可以完成这个任务,但过程会显得很繁琐:点击对象,选择动作,点击按钮……一定有更方便的方法吧?让我们找到一种只需单击一下即可完成所有操作的方法。这次我们要实现另一个奶奶的HTC创意。她希望她能给某些编辑发电子邮件,告诉他们她喜欢的所有照片。classPictureAdmin(admin.ModelAdmin):list_fields=(...,'mail_link',)defmail_link(self,obj):dest=reverse('admin:myapp_pictures_mail_author',kwargs={'pk':obj.pk})return'{title}'.format(url=dest,title='sendmail')mail_link.short_description='Showsomelove'mail_link.allow_tags=Truedefget_urls(self):urls=[url('^(?P\d+)/sendaletter/?$',self.admin_site.admin_view(self.mail_view),name='myapp_pictures_mail_author'),]returnurls+super(PictureAdmin,self).get_urls()defmail_view(self,request,*args,**kwargs):obj=get_object_or_404(Picture,pk=kwargs['pk'])send_mail('Feelthegranny'slove','Hey,shelovesyourpet!','granny@yoursite.com',[obj.author.email])self.message_user(request,'Theletterisonitsway')returnredirect(reverse('admin:myapp_picture_changelist'))我希望她现在满意了。现在每个对象字段都添加了一个链接,允许她单击一下即可发送电子邮件。额外提示:只需为管理员添加一行代码即可减少查询Django管理员(Django也是)最常见和有用的技巧是select_related。呃,你已经知道了?不就是把对象的名字传递给ModelAdmin的list_select_related属性,实现相关对象的预加载吗。但是,您知道您没有描述所有相关对象吗?只要设置为True,Django就可以自动预加载外部对象:classPictureAdmin(admin.ModelAdmin):list_select_related=True这篇文章就快结束了,希望你能觉得有趣。不要忘记在评论中分享您的想法,并告诉我们对您有帮助的技巧。