我正在浏览Mozilla的django tutorial。他们基本上创建了一个公共图书馆。他们并没有真正谈论ManyToMany关系,并且已经设置好了,因此一本书只能有一个作者。
在完成本教程的过程中,我决定不再复制本地库,而是尝试创建IMDB的基本功能。所以我最终只是基本上复制和粘贴代码而不是学习任何东西。
我已经设置了一个展示可以让很多创作者使用ManyToMany字段的方式。在我的类创建者中,我有两个变量 first_name 和 last_name 。我有另一个类Show ,它有很多其他变量。
现在在名为show的应用程序的 admin.py 中,我想要它,以便在我的ShowAdmin中,它将显示admin表中的创建者。问题在于Django不支持ManyToMany,因为查询负担很大。
Now my possible solution is to:
1) create an empty array
2) loop through the first_name array and add it to the empty array.
3) loop through the last_array and add it to the empty array
4) then join the array to get my desired result of "last_name, first_name" in the admin table.
在我开始讨论之前,我想知道是否有更简单的方法可以解决这个问题?我不太了解python和django,(或者一般关于编程),所以如果可能,你能ELI5吗?
以下是我的模特和我的管理员:
Admin.py :
from django.contrib import admin
from .models import Show, Creator, Cast, Language, Genre
class ShowAdmin(admin.ModelAdmin):
list_display =('title','language','display_genre', 'display_creator')
# Register your models here.
admin.site.register(Show, ShowAdmin)
admin.site.register(Creator)
admin.site.register(Cast)
admin.site.register(Language)
admin.site.register(Genre)
Models.py (至于我的模特,有什么我做错了或者会给我带来很多麻烦吗?)
from django.db import models
from django.urls import reverse
class Genre(models.Model):
name = models.CharField(max_length=200, help_text="Enter a show genre (e.g. Action, Drama, etc.)")
def __str__(self):
return self.name
class Language(models.Model):
name = models.CharField(max_length=200, help_text="Enter a show's language (e.g. English, Japanese, etc.)")
def __str__(self):
return self.name
class Creator(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Meta:
ordering = ['first_name','last_name']
def get_absolute_url(self):
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
return '{0}, {1}'.format(self.first_name,self.last_name)
class Show(models.Model):
title = models.CharField(max_length=200)
creator = models.ManyToManyField(Creator, help_text="Select a creator(s)")
genre = models.ManyToManyField(Genre, help_text='Select a genre for this book')
language = models.ForeignKey('Language', on_delete=models.SET_NULL, null=True)
summary = models.TextField(max_length=1000, help_text='Enter a brief description of the show', null=True)
cast = models.ManyToManyField(Cast, help_text="Select cast")
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('show-detail', args=[str(self.id)])
def display_genre(self):
return ', '.join([ genre.name for genre in self.genre.all()[:3] ])
def display_creator(self):
return ', '.join([creator.first_name for creator in self.creator.all()[:3]])
display_creator.short_description = 'Creator'
display_genre.short_description = 'Genre'
奖金问题(如果你有时间):通过管理员添加节目肯定是可能的,但在我看来效率不高。在我的工作模型中,如果我想在节目中添加创作者,我必须经过大量选择并选择正确的人。现在让我们说我的数据库有1000个创建者,向下滚动所有选项并找到正确的人是不太实际的。现在我认为我只是在教程的第4部分(AdminSite),是否有更实用的方法在节目中添加创作者?
我知道这篇文章真的很长,我很抱歉。但我只是想说谢谢你的时间。我真的很感激。
答案 0 :(得分:1)
您可以将生成器表达式与join()
:
def get_creator_names(self, obj):
return ', '.join('{} {}'.format(creator.first_name, creator.last_name) for creator in obj.creators.all()