django 外键显示

1 投票
2 回答
2039 浏览
提问于 2025-04-16 23:07

更新的回答:我怎么才能在显示药物时,让一个查找值(来自Atc)在交易表(药物)上显示出来?

解决方案是使用Saverio的方法,把关系直接嵌入到模型里:

在models.py文件中

class Atc(models.Model):
    id = models.CharField(max_length=60, primary_key=True, db_column='ID') 
    txt = models.CharField(max_length=690, db_column='TXT')
    class Meta:
        db_table = u'ATC'
    def __unicode__(self):
    return u"%s - %s" % (self.id, self.txt)

class Drug(models.Model):
    id = models.CharField(max_length=64, primary_key=True, db_column='ID')
    atc = models.ForeignKey(Atc, db_column='ATCCD')
    pricetopharm = models.FloatField(db_column='PRICETOPHARM')
    brandnm = models.CharField(max_length=135, db_column='BRANDNM')
    drugnm = models.CharField(max_length=240, db_column='DRUGNM')
    class Meta:
        db_table = u'DRUGS'
    def __unicode__(self):
    return u"%s - %s" %(self.drugnm, self.formandstrength)

然后在admin.py文件中

class DrugsAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['id']}),
        ('ATC',          {'fields': ['atc','brandnm'] }),
        (None,           {'fields': ['drugnm']}),
        ('Prices',       {'fields': ['pricetopharm']}),
    ]
    search_fields = ['drugnm','brandnm']

admin.site.register(Drug, DrugsAdmin)
admin.site.register(Atc)

关键点是要在models.py中添加内容

atc = models.ForeignKey(Atc, db_column='ATCCD')

到药物(交易,而不是参考表)中,以及

('ATC',          {'fields': ['atc','brandnm'] }),

到admin.py的字段集合中,以表示多对一的关系。

现在,admin.py的内容就不那么重要了(这在MTV理念中是应该的。此外,把对象的名称改为单数形式(药物,而不是药物们)也很有帮助,至少避免了重复的s(比如药物们变成药物)。最终,药物的显示会出现一个下拉框,里面有id和文本,比如P04H11 - Cytotoxics。

谢谢大家的帮助!

(我太菜了,无法自己回答问题,所以才编辑了原来的问题!)

2 个回答

0

你是怎么获取那个描述的?如果有代码的话发出来,这样我们可能能更好地帮你!

你需要用你的 notesid 来获取 notesinline 对象并显示出来!

fetched_note = NotesInline.objects.filter(id=notesid)

这里的 notesid 就是你 DrugsAdmin 对象的一个变量哦 :)

0

为什么不直接这样做呢

class Atc(models.Model): # in models.py
    drug = models.ForeignKey('Drug')
    description = models.CharField(max_length=10000)
    def __unicode__(self): return u"%s - %s" % (self.id, self.description)

class AtcInline(admin.StackedInline): # in admin.py
    # set option for not being able to add more than one.
    model = Atc
    fields = ['description']

这样做会在表单的内联部分直接显示与你的药物实例相关的内容。

另外,值得注意的是,通常在django中,模型的名称是单数形式,比如用Drug而不是Drugs。这样用起来更合适,比如在Drug.objects.filter()drug = Drug()中。

补充:关于数据库结构和数据模型的进一步考虑

看起来你有一个之前的数据库结构可以使用。如果你不能更改列名,至少可以给你的属性起一些更有意义的名字,这样代码会更容易读懂:

class AtcClassification(models.Model):
    code = models.CharField(max_length=60, primary_key=True, db_column='ID') 
    description = models.CharField(max_length=690, db_column='TXT')

class Drug(models.Model):
    id = models.CharField(max_length=64, primary_key=True, db_column='ID')
    atc_classification = models.ForeignKey(AtcClassification, db_column='ATCCD')
    price_to_pharmacy = models.FloatField(db_column='PRICETOPHARM')
    brand_name = models.CharField(max_length=135, db_column='BRANDNM')
    drug_name = models.CharField(max_length=240, db_column='DRUGNM')
    form_and_strength = models...

    class Meta:
        db_table = u'DRUGS'

    def __unicode__(self):
        return u"%s - %s" %(self.drug_name, self.form_and_strength)

    def atc_description(self): return self.atc_classification.description
    def atc_code(self): return self.atc_classification.code

如果你也拥有数据库结构,一旦数据模型完成,可以使用类似South迁移的工具(db.rename(table_name, old_column_name, new_column_name))来同步数据库结构和你现在更易读的数据模型。

撰写回答