You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何通过主键自动关联拆分的患者模型?

Django患者存储系统自动关联拆分模型解决方案

一、模型关联基础配置

首先确保Hasta、HastaProfil、HastaAliskanlik三个模型通过一对一关联绑定,示例代码如下:

# models.py
from django.db import models

class Hasta(models.Model):
    # 基础患者信息
    ad = models.CharField(max_length=100, verbose_name="姓名")
    soyad = models.CharField(max_length=100, verbose_name="姓氏")
    telefon = models.CharField(max_length=20, verbose_name="电话")
    # 其他基础字段...

class HastaProfil(models.Model):
    hasta = models.OneToOneField(
        Hasta, 
        on_delete=models.CASCADE, 
        related_name="profil",
        verbose_name="关联患者"
    )
    # 档案类字段
    boy = models.FloatField(verbose_name="身高")
    kilo = models.FloatField(verbose_name="体重")
    # 其他300个拆分字段...

class HastaAliskanlik(models.Model):
    hasta = models.OneToOneField(
        Hasta, 
        on_delete=models.CASCADE, 
        related_name="aliskanlik",
        verbose_name="关联患者"
    )
    # 习惯类字段
    sigara_kullanimi = models.BooleanField(verbose_name="吸烟", default=False)
    alkol_kullanimi = models.BooleanField(verbose_name="饮酒", default=False)
    # 其他拆分字段...

二、Admin面板自动关联实现

方法1:内联模型(Inline)同步编辑

将子模型嵌入Hasta的Admin页面,创建/编辑患者时可直接填写关联模型数据,自动完成绑定:

# admin.py
from django.contrib import admin
from .models import Hasta, HastaProfil, HastaAliskanlik

class HastaProfilInline(admin.StackedInline):
    model = HastaProfil
    can_delete = False  # 禁止单独删除档案,需随患者删除
    verbose_name_plural = "患者档案"
    # 如果字段太多,可设置fieldsets拆分显示

class HastaAliskanlikInline(admin.StackedInline):
    model = HastaAliskanlik
    can_delete = False
    verbose_name_plural = "患者习惯"

@admin.register(Hasta)
class HastaAdmin(admin.ModelAdmin):
    inlines = [HastaProfilInline, HastaAliskanlikInline]
    list_display = ("ad", "soyad", "telefon")  # 列表显示字段

配置后,在Admin中创建Hasta时,下方会直接显示HastaProfil和HastaAliskanlik的表单,提交后自动创建关联记录,无需手动选择。

方法2:自动创建关联子模型

如果需要单独管理子模型,可在Hasta的save方法中自动生成关联记录:

# models.py - Hasta类中添加
def save(self, *args, **kwargs):
    is_new = not self.pk  # 判断是否为新创建的患者
    super().save(*args, **kwargs)
    if is_new:
        # 自动创建关联的档案和习惯记录
        HastaProfil.objects.create(hasta=self)
        HastaAliskanlik.objects.create(hasta=self)

这样新增患者后,对应的HastaProfil和HastaAliskanlik会自动生成,在Admin中编辑子模型时,关联字段会默认选中对应的患者。

三、批量添加患者处理

使用bulk_create批量导入患者时,需手动批量创建关联子模型(因为bulk_create不会触发模型的save方法):

# 批量创建患者
hasta_list = [
    Hasta(ad="Ahmet", soyad="Yılmaz", telefon="05551234567"),
    Hasta(ad="Ayşe", soyad="Kaya", telefon="05559876543"),
    # 更多患者数据...
]
Hasta.objects.bulk_create(hasta_list)

# 批量创建关联档案
profil_list = [HastaProfil(hasta=hasta) for hasta in hasta_list]
HastaProfil.objects.bulk_create(profil_list)

# 批量创建关联习惯
aliskanlik_list = [HastaAliskanlik(hasta=hasta) for hasta in hasta_list]
HastaAliskanlik.objects.bulk_create(aliskanlik_list)

四、患者自助注册实现

整合式表单(单页提交)

创建整合三个模型字段的表单,在视图中统一处理保存:

# forms.py
from django import forms
from .models import Hasta, HastaProfil, HastaAliskanlik

class HastaKayitForm(forms.Form):
    # 患者基础字段
    ad = forms.CharField(max_length=100, label="姓名")
    soyad = forms.CharField(max_length=100, label="姓氏")
    telefon = forms.CharField(max_length=20, label="电话")
    # 档案字段
    boy = forms.FloatField(label="身高")
    kilo = forms.FloatField(label="体重")
    # 习惯字段
    sigara_kullanimi = forms.BooleanField(label="吸烟", required=False)
    alkol_kullanimi = forms.BooleanField(label="饮酒", required=False)
    # 其他300个字段按需添加...

    def save(self):
        # 先保存基础患者信息
        hasta = Hasta.objects.create(
            ad=self.cleaned_data["ad"],
            soyad=self.cleaned_data["soyad"],
            telefon=self.cleaned_data["telefon"]
        )
        # 保存档案
        HastaProfil.objects.create(
            hasta=hasta,
            boy=self.cleaned_data["boy"],
            kilo=self.cleaned_data["kilo"]
        )
        # 保存习惯
        HastaAliskanlik.objects.create(
            hasta=hasta,
            sigara_kullanimi=self.cleaned_data["sigara_kullanimi"],
            alkol_kullanimi=self.cleaned_data["alkol_kullanimi"]
        )
        return hasta
# views.py
from django.shortcuts import render, redirect
from .forms import HastaKayitForm

def hasta_kayit(request):
    if request.method == "POST":
        form = HastaKayitForm(request.POST)
        if form.is_valid():
            hasta = form.save()
            return redirect("hasta_detay", pk=hasta.pk)  # 跳转至患者详情页
    else:
        form = HastaKayitForm()
    return render(request, "hasta_kayit.html", {"form": form})

分步骤表单(优化长表单体验)

如果300个字段过于冗长,可采用分步骤提交:

  1. 第一步提交患者基础信息,将数据存入session
  2. 第二步提交档案信息,更新session
  3. 第三步提交习惯信息,从session取出所有数据,批量保存三个模型

示例视图逻辑:

# views.py
def kayit_adim1(request):
    if request.method == "POST":
        # 处理基础字段,存入session
        request.session["hasta_bilgi"] = {
            "ad": request.POST.get("ad"),
            "soyad": request.POST.get("soyad"),
            "telefon": request.POST.get("telefon")
        }
        return redirect("kayit_adim2")
    return render(request, "kayit_adim1.html")

def kayit_adim2(request):
    if request.method == "POST":
        request.session["profil_bilgi"] = {
            "boy": request.POST.get("boy"),
            "kilo": request.POST.get("kilo")
        }
        return redirect("kayit_adim3")
    return render(request, "kayit_adim2.html")

def kayit_adim3(request):
    if request.method == "POST":
        # 取出session数据,保存所有模型
        hasta_bilgi = request.session.get("hasta_bilgi")
        profil_bilgi = request.session.get("profil_bilgi")
        aliskanlik_bilgi = {
            "sigara_kullanimi": request.POST.get("sigara_kullanimi") == "on",
            "alkol_kullanimi": request.POST.get("alkol_kullanimi") == "on"
        }

        hasta = Hasta.objects.create(**hasta_bilgi)
        HastaProfil.objects.create(hasta=hasta, **profil_bilgi)
        HastaAliskanlik.objects.create(hasta=hasta, **aliskanlik_bilgi)

        # 清空session
        del request.session["hasta_bilgi"]
        del request.session["profil_bilgi"]
        return redirect("hasta_detay", pk=hasta.pk)
    return render(request, "kayit_adim3.html")

内容的提问来源于stack exchange,提问作者Prusa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:21:11