我正在编写一个Django应用程序来跟踪我的魔术卡收藏。我现在对模型非常满意,并且管理界面可以正常工作。我可以添加新的卡片,卡片的收藏夹和副本,并且一切正常。但是,我现在想将我的整个模型关系中的属性添加到“管理”部分中的list_display。
基本上,我想列出每个集合的副本,copys_foil和copyss_premium,以及每个卡的条目。 (每个集合可以具有同一张卡的多个普通副本,铝箔副本和高级副本。)我想在管理UI的list_display中以及以后在视图中同时列出它们。我该怎么办?
这是我的模型。py:
from django.db import models
class Expansion(models.Model):
name = models.CharField(max_length=100, unique=True, verbose_name='Expansion')
symbol = models.CharField(max_length=3, unique=True, primary_key=True, verbose_name='Expansion Symbol')
released = models.DateField()
added = models.DateField(auto_now_add=True)
modified = models.DateField(auto_now=True)
def __str__(self):
return '%s' % (self.symbol)
class Card(models.Model):
LAND = 'L'
COMMON = 'C'
UNCOMMON = 'U'
RARE = 'R'
MYTHIC = 'M'
TOKEN = 'T'
RARITY_CHOICES = (
(LAND, 'Land'),
(COMMON, 'Common'),
(UNCOMMON, 'Uncommon'),
(RARE, 'Rare'),
(MYTHIC, 'Mythic Rare'),
(TOKEN, 'Token'),
)
WHITE = 'W'
BLUE = 'U'
BLACK = 'B'
RED = 'R'
GREEN = 'G'
COLOURLESS = 'C'
GOLD = 'M'
COLOUR_CHOICES = (
(WHITE, 'White'),
(BLUE, 'Blue'),
(BLACK, 'Black'),
(RED, 'Red'),
(GREEN, 'Green'),
(COLOURLESS, 'Colourless'),
(GOLD, 'Gold'),
)
WHITE = 'W'
BLUE = 'U'
BLACK = 'B'
RED = 'R'
GREEN = 'G'
REDGREEN = 'RG'
BLACKGREEN = 'BG'
WHITEREDGREEN = 'WRG'
BLUEBLACKRED = 'UBR'
COLOUR_CHOICES_IND = (
(WHITE, 'White'),
(BLUE, 'Blue'),
(BLACK, 'Black'),
(RED, 'Red'),
(GREEN, 'Green'),
(REDGREEN, 'Red/Green'),
(BLACKGREEN, 'Black/Green'),
(WHITEREDGREEN, 'White/Red/Green'),
(BLUEBLACKRED, 'Blue/Black/Red'),
)
name = models.CharField(max_length=200)
name_transformed = models.CharField(max_length=200, blank=True, verbose_name='Name (Transformed)',
help_text='For double-sided cards')
slug = models.SlugField(max_length=220, unique=True, primary_key=True,
help_text='Example: totallylost-gtc-054')
colour = models.CharField(
max_length=1,
choices=COLOUR_CHOICES,
default='COLOURLESS',
verbose_name='Colour'
)
cost_w = models.IntegerField(blank=True, null=True, verbose_name='Cost White')
cost_u = models.IntegerField(blank=True, null=True, verbose_name='Cost Blue')
cost_b = models.IntegerField(blank=True, null=True, verbose_name='Cost Black')
cost_r = models.IntegerField(blank=True, null=True, verbose_name='Cost Red')
cost_g = models.IntegerField(blank=True, null=True, verbose_name='Cost Green')
cost_c = models.IntegerField(blank=True, null=True, verbose_name='Cost Generic')
cost_wu = models.IntegerField(blank=True, null=True, verbose_name='Cost White/Blue')
cost_wb = models.IntegerField(blank=True, null=True, verbose_name='Cost White/Black')
cost_cw = models.IntegerField(blank=True, null=True, verbose_name='Cost Generic/White')
cost_ub = models.IntegerField(blank=True, null=True, verbose_name='Cost Blue/Black')
cost_ur = models.IntegerField(blank=True, null=True, verbose_name='Cost Blue/Red')
cost_cu = models.IntegerField(blank=True, null=True, verbose_name='Cost Generic/Blue')
cost_br = models.IntegerField(blank=True, null=True, verbose_name='Cost Black/Red')
cost_bg = models.IntegerField(blank=True, null=True, verbose_name='Cost Black/Green')
cost_cb = models.IntegerField(blank=True, null=True, verbose_name='Cost Generic/Black')
cost_rg = models.IntegerField(blank=True, null=True, verbose_name='Cost Red/Green')
cost_rw = models.IntegerField(blank=True, null=True, verbose_name='Cost Red/White')
cost_cr = models.IntegerField(blank=True, null=True, verbose_name='Cost Generic/Red')
cost_gw = models.IntegerField(blank=True, null=True, verbose_name='Cost Green/White')
cost_gu = models.IntegerField(blank=True, null=True, verbose_name='Cost Green/Blue')
cost_cg = models.IntegerField(blank=True, null=True, verbose_name='Cost Generic/Green')
art = models.FileField(upload_to='img/card/', blank=True)
art_transformed = models.FileField(upload_to='img/card/', blank=True, verbose_name='Art (Flip Side)',
help_text='For double-sided cards')
colour_indicator = models.CharField(
max_length=5,
choices=COLOUR_CHOICES_IND,
default='',
blank=True,
verbose_name='Colour Indicator'
)
supertype = models.CharField(max_length=50, blank=True)
type = models.CharField(max_length=50, blank=True)
subtype = models.CharField(max_length=50, blank=True)
colour_indicator_transformed = models.CharField(
max_length=5,
choices=COLOUR_CHOICES_IND,
default='',
blank=True,
verbose_name='Colour Indicator',
help_text='For double-sided cards'
)
supertype_transfomed = models.CharField(max_length=50, blank=True, verbose_name='Supertype (Transformed)',
help_text='For double-sided cards')
type_transformed = models.CharField(max_length=50, blank=True, verbose_name='Type (Transformed)',
help_text='For double-sided cards')
subtype_transformed = models.CharField(max_length=50, blank=True, verbose_name='Subtype (Transformed)',
help_text='For double-sided cards')
expansion = models.ForeignKey(Expansion,
on_delete=models.CASCADE)
power = models.IntegerField(blank=True, null=True, help_text='(Creatures)')
toughness = models.IntegerField(blank=True, null=True)
loyalty = models.IntegerField(blank=True, null=True, help_text='(Planeswalkers)')
power_transformed = models.IntegerField(blank=True, null=True, verbose_name='Power (Transformed)',
help_text='For double-sided cards')
toughness_transformed = models.IntegerField(blank=True, null=True, verbose_name='Toughness (Transformed)',
help_text='For double-sided cards')
loyalty_transformed = models.IntegerField(blank=True, null=True, verbose_name='Loyalty (Transformed)',
help_text='For double-sided cards')
rules = models.TextField(blank=True, verbose_name='Rules Text')
flavour = models.TextField(blank=True, verbose_name='Flavour Text')
rules_transformed = models.TextField(blank=True, verbose_name='Rules Text (Transformed)',
help_text='For double-sided cards')
flavour_transformed = models.TextField(blank=True, verbose_name='Flavour Text (Transformed)',
help_text='For double-sided cards')
number = models.IntegerField(blank=True, null=True, verbose_name='Collector Number')
max_number = models.IntegerField(blank=True, null=True, verbose_name='...of')
rarity = models.CharField(
max_length=1,
choices=RARITY_CHOICES,
default=COMMON,
verbose_name='Rarity'
)
artist = models.CharField(max_length=50, blank=True)
artist_transformed = models.CharField(max_length=50, blank=True, verbose_name='Artist (Flip Side)',
help_text='For double-sided cards')
errata = models.TextField(blank=True, help_text='Notes and Rulings on this card')
url = models.URLField(max_length=220, unique=True, verbose_name='Scryfall URL')
added = models.DateField(auto_now_add=True)
modified = models.DateField(auto_now=True)
def __str__(self):
return '%s (%s)' % (self.name, self.expansion)
class Collection(models.Model):
name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True, primary_key=True)
added = models.DateField(auto_now_add=True)
modified = models.DateField(auto_now=True)
cards = models.ManyToManyField(Card, through='Copy')
def __str__(self):
return '%s' % (self.name)
class Copy(models.Model):
class Meta:
verbose_name_plural = 'copies'
card = models.ForeignKey(Card, on_delete=models.CASCADE)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
added = models.DateField(auto_now_add=True)
copies = models.IntegerField(blank=True, null=True)
copies_foil = models.IntegerField(blank=True, null=True, verbose_name='Foil Copies')
copies_premium = models.IntegerField(blank=True, null=True, verbose_name='Premium Copies')
def __str__(self):
return ''
这是我的admin.py:
from django.contrib import admin
from django.utils.html import format_html
from .models import Expansion, Card, Collection, Copy
class CopyInline(admin.TabularInline):
model = Copy
extra = 1 # extra rows below in the admin view
class CardAdmin(admin.ModelAdmin):
inlines = (CopyInline,)
fieldsets = [
(None, {'fields': ['name', 'name_transformed', 'slug', 'colour']}),
('Card Cost', {'fields': [('cost_w', 'cost_u', 'cost_b'), ('cost_r',
'cost_g', 'cost_c'), ('cost_wu', 'cost_wb',
'cost_cw'), ('cost_ub', 'cost_ur', 'cost_cu'),
('cost_br', 'cost_bg', 'cost_cb'), ('cost_rg',
'cost_rw', 'cost_cr'), ('cost_gw', 'cost_gu',
'cost_cg')]}),
('Type Line', {'fields': [('colour_indicator', 'supertype', 'type', 'subtype')]}),
('Type Line (Transformed)', {'fields': [('colour_indicator_transformed', 'supertype_transfomed',
'type_transformed', 'subtype_transformed')]}),
(None, {'fields': ['art', 'art_transformed', 'expansion']}),
(None, {'fields': [('power', 'power_transformed',
'toughness', 'toughness_transformed')]}),
(None, {'fields': [('loyalty', 'loyalty_transformed')]}),
(None, {'fields': [('rules', 'rules_transformed')]}),
(None, {'fields': [('flavour', 'flavour_transformed')]}),
(None, {'fields': [('number', 'max_number')]}),
(None, {'fields': ['rarity']}),
(None, {'fields': [('artist', 'artist_transformed')]}),
(None, {'fields': ['errata', 'url']})
]
list_display = ('name', 'colour', 'expansion', 'number', 'rarity', 'show_url')
list_filter = ['colour', 'expansion__name', 'rarity']
def show_url(self, obj):
return format_html("<a href='{url}'>{url}</a>", url=obj.url)
show_url.short_description = "Scryfall URL"
admin.site.register(Expansion)
admin.site.register(Card, CardAdmin)
admin.site.register(Collection)
答案 0 :(得分:2)
您可以定义一个名为count_copies
的函数,并在列表管理员中显示该函数的输出,如下所示。请注意,以下假设每个Copy
对象都绑定到唯一的Card
。从您的数据库结构中,我不确定为什么这是两个单独的模型。
from .models import Copy
class CardAdmin(admin.ModelAdmin):
list_display = (..., 'count_copies')
def count_copies(self, obj):
try:
c = Copy.objects.get(card=obj)
except Copy.DoesNotExist:
c = None
if c:
return c.copies
else:
return 0