2016-01-11 111 views
1

假设我有汽车 - suv /巴士模型。django管理员抽象基类?

我想列出所有的汽车在Django管理员(具有名称属性)。
当用户点击其中一辆车时,它会转到SUV或公交车型号的相应详细页面。

如何创建一个这样的管理列表页面?

class Car: 

    name = models.CharField() 

    class Meta: 
     abstract=True 


class Suv(Car): 

    pass 

class Bus(Car): 

    pass 

回答

2

不知道这是最好的方法,但在这里分享我的解决方案。

首先,创建一个数据库视图

create view [app_label_model_name] as 

select id, name, 1 as car_type 
from suv 
union 
select id, name, 2 as car_type 
from bus 
order by something; 

然后创建非manged模型

class PostBaseView(models.Model): 
    # this would be CarBaseView, I'm copying my actual code 
    id = models.IntegerField() 
    raw_html = models.TextField(null=True) 
    created_at = models.DateTimeField(primary_key=True) 
    post_type = models.IntegerField() 

    class Meta: 
     managed = False 

然后,从管理页面,更改基于子类型的链接。

class ChangeList(ChangeListDefault): 

    def url_for_result(self, result): 
     # pk = getattr(result, self.pk_attname) 
     id = result.id 

     app_label = result.get_app_label() 
     model_name = result.get_model_name() 

     return reverse('admin:%s_%s_change' % (app_label, 
               model_name), 
         args=(quote(id),)) 


class PostBaseViewAdmin(admin.ModelAdmin): 

    list_display = ['__str__', 'post_type_str'] 

    class Meta: 
     model = PostBaseView 

    def get_changelist(self, request, **kwargs): 
     """ 
     Returns the ChangeList class for use on the changelist page. 
     """ 
     return ChangeList 

admin.site.register(PostBaseView, PostBaseViewAdmin) 

volla你有一个管理员在一个列表中显示多个子类。

+1

这个答案比我好得多,谢谢! –

+0

这仍然是最好的解决方案吗? – ratata

0

你需要让你的Car不是一个抽象的模型,你必须有一些基本表为您的车辆。

class Car: 
    name = models.CharField() 
    class Meta: 
     abstract = False 

class Suv(Car): 
    pass 

class Bus(Car): 
    pass 

class CarAdmin(admin.ModelAdmin): 
    model = Car 

但是,这里容易的事情结束。管理员没有针对您的任务的内置解决方案。我建议你重写至少CarAdmin.get_form()CarAdmin.get_queryset()方法,但我不确定它们是唯一必须自定义的方法。

0

我认为this answer是适用的。 ModelAdmin需要知道外键项是只读的,并且在称为readonly_fields的元组中指定。

使用带我来这里有问题,我有(models.py):

class Choice(models.Model): 
    question = models.ForeignKey(Question, on_delete=models.CASCADE) 
    choice_text = models.CharField(max_length=200) 
    def __str__(self): 
     return self.choice_text 
class Answer(models.Model):  
    question = models.ForeignKey(Question, on_delete=models.CASCADE) 
    user = models.ForeignKey(User, on_delete=models.CASCADE, default = 1) 
    class Meta: 
     abstract = True 
class Vote(Answer): 
choice = models.ForeignKey(Choice, on_delete=models.CASCADE) 
def answer(self): 
    return self.choice 
def __str__(self): 
    return self.choice.choice_text 

和(admin.py):

class VoteAdmin(admin.ModelAdmin): 
#list_display = ('Answer.question.question_text', 'Answer.User.user_id', 'Choice.choice_text') 
readony_fields = ('question', 'user') 
list_display = ('question', 'user', 'choice') 
fieldsets = [ 
     ('Question', {'fields': ['question']}), 
     ('User', {'fields': ['user']}), 
     ('Vote', {'fields' : ['choice']}), 
     ] 

希望这会证明是有用的,以未来的搜索。