Django Models创建单任务分配给所有用户且各人状态独立的问题咨询
解决方案
核心思路
你需要把「用户-任务的完成状态」从任务主表剥离,存到多对多关联的中间表中,每个「用户+任务」的组合对应一条独立的状态记录,既能保留单条任务主记录的公共属性,又能实现不同用户的状态互不干扰。
具体实现步骤
1. 调整模型结构
- 删除
Tps表中的users外键字段、status布尔字段 - 新增用户-任务关联中间表,存储每个用户对应任务的独立状态
- 给
Tps表新增多对多字段关联Usuario,通过through参数指定自定义中间表
修改后的代码示例:
from django.db import models from django.contrib.auth.models import AbstractUser from django.utils import timezone from django.db.models.signals import post_save from django.dispatch import receiver class Usuario(AbstractUser): pass # 新增用户-任务状态中间表 class UsuarioTpsEstado(models.Model): usuario = models.ForeignKey(Usuario, on_delete=models.CASCADE) tps = models.ForeignKey('Tps', on_delete=models.CASCADE) # 状态放在中间表,每个用户-任务组合单独存储 status = models.BooleanField(default=True) class Meta: # 保证每个用户和同一个任务只有一条状态记录 unique_together = ('usuario', 'tps') class Tps(models.Model): # 多对多关联用户,通过自定义中间表 usuarios = models.ManyToManyField(Usuario, through=UsuarioTpsEstado, related_name='tps_list') titulo = models.CharField(max_length=100) TECNOLOGIA_DE_LA_FABRICACION = 'TDF' MANTENIMIENTO_Y_REPARACION_DE_EQUIPOS = 'MYRDE' MAQUINAS_ELECTRICAS_Y_ENSAYOS = 'MEYE' SEGURIDAD_E_HIGIENE_INDUSTRIAL = 'SEHI' LABORATORIO_DE_ENSAYOS_INDUSTRIALES = 'LDEI' INSTALACIONES_INDUSTRIALES = 'II' RELACIONES_HUMANAS = 'RH' TALLER_DE_ELECTROMECANICA = 'TE' ORGANIZACION_INDUSTRIAL = 'OI' INSTALACIONES_ELECTRICAS = 'IE' EDUCACION_FISICA = 'EF' EQUIPOS_Y_APARATOS_DE_MANIOBRA_Y_TRANSPORTE = 'EYADMYT' MATERIAS_CHOICES = [ (TECNOLOGIA_DE_LA_FABRICACION, 'Tecnologia de la fabricación'), (MANTENIMIENTO_Y_REPARACION_DE_EQUIPOS, 'Mantenimiento y R de equipos'), (MAQUINAS_ELECTRICAS_Y_ENSAYOS, 'Máquinas eléctricas y ensayos'), (SEGURIDAD_E_HIGIENE_INDUSTRIAL, 'Seguridad e higiene industrial'), (LABORATORIO_DE_ENSAYOS_INDUSTRIALES, 'Laboratorio de ensayos industriales'), (INSTALACIONES_INDUSTRIALES, 'Instalaciones industriales'), (RELACIONES_HUMANAS, 'Relaciones humanas'), (TALLER_DE_ELECTROMECANICA, 'Taller de electromecánica'), (ORGANIZACION_INDUSTRIAL, 'Organización industrial'), (INSTALACIONES_ELECTRICAS, 'Instalaciones eléctricas'), (EDUCACION_FISICA, 'Educacion fisica'), (EQUIPOS_Y_APARATOS_DE_MANIOBRA_Y_TRANSPORTE, 'Equipos y aparatos de maniobra y transporte') ] materia = models.CharField( max_length=8, choices=MATERIAS_CHOICES, default=None) fecha_actual = models.DateField(default=timezone.now) fecha_entrega = models.DateField(auto_now=False, auto_now_add=False) material = models.URLField() consignas = models.URLField() def __str__(self): return self.titulo
2. 实现任务自动分配
新增Django信号,自动完成两个场景的分配:
- 新建任务时,自动给所有现有用户创建状态记录
- 新增用户时,自动给所有现有任务创建状态记录
追加信号代码:
# 新建任务时,自动分配给所有用户 @receiver(post_save, sender=Tps) def asignar_tps_a_todos_usuarios(sender, instance, created, **kwargs): if created: usuarios = Usuario.objects.all() # 批量创建中间表记录,性能更高 UsuarioTpsEstado.objects.bulk_create([ UsuarioTpsEstado(usuario=usuario, tps=instance) for usuario in usuarios ]) # 新增用户时,自动分配所有现有任务给该用户 @receiver(post_save, sender=Usuario) def asignar_todos_tps_a_usuario(sender, instance, created, **kwargs): if created and not instance.is_superuser: # 可以按需过滤不需要分配的用户 tps_list = Tps.objects.all() UsuarioTpsEstado.objects.bulk_create([ UsuarioTpsEstado(usuario=instance, tps=tps) for tps in tps_list ])
3. 状态读写操作示例
- 查询当前用户的所有任务及状态:
# 当前登录用户为 request.user tps_estados = UsuarioTpsEstado.objects.filter(usuario=request.user).select_related('tps') for estado in tps_estados: print(f"任务名:{estado.tps.titulo},完成状态:{estado.status}")
- 用户修改任务状态:
# 前端传入要修改的任务id tps_id UsuarioTpsEstado.objects.filter(usuario=request.user, tps_id=tps_id).update(status=False)
内容的提问来源于stack exchange,提问作者Franper16
相关产品推荐
相关产品推荐

