多模型 类 Django 的可重用视图方法
Reusable views method for multiple model classes Django
伙计们,我想创建一个工具清单应用程序。
我有这种方法可以对所有工具类型执行完全相同的操作。我想知道的是如何使用此方法动态选择要使用的模型(也许如何将模型 class 作为参数传递)。
它目前仅适用于一种类型的工具。我的 models.py 有一个抽象模型,它包含所有工具的所有公共字段,然后是针对工具特定字段继承它的各种模型(e.i。立铣刀、钻头-钻头、钳子、螺丝刀等都继承了我的抽象模型的通用字段。
def calcular_nueva_cantidad(ce, up, get_link):
if get_link == 'incremento':
total = ce + up
else:
total = -(ce - up)
return total
def calcular_nuevo_total(nce, pu):
total = nce * pu
return total
# crea el formulario para la actualizacion de cantidad existente
class updateForm(forms.Form):
update = forms.IntegerField()
def actualizar_cantidad(request, pk, model ):
# trae de la base de datos el valor de la cantidad_existente
cantidad_existente = model.objects.filter(pk=pk).values('cantidad_existente')
c = cantidad_existente.values_list('cantidad_existente', flat=True)
ce = c[0]
# trae de la base de datos el valor de la precio_unitario
precio_unitario = model.objects.filter(pk=pk).values('precio_unitario')
p = precio_unitario.values_list('precio_unitario', flat=True)
pu = p[0]
# trae de la base de datos el valor de la total
qs_total = model.objects.filter(pk=pk).values('total')
if request.method =='POST':
form = updateForm(request.POST)
if form.is_valid():
# Obtiene el name de urls para el link segun sea el caso
get_link = resolve(request.path_info).url_name
get_linkwargs = resolve(request.path_info).kwargs
print(F'========>{get_link, get_linkwargs }<=========')
up = form.cleaned_data['update']
# Calcula el nuevo valor de cantidad existente
nce = calcular_nueva_cantidad(up, ce, get_link)
# Actualiza la nueva cantidad existente
cantidad_existente.update(cantidad_existente=nce)
# Calcula el nuevo valor de cantidad existente
s_total = calcular_nuevo_total(nce, pu)
# Actualiza la nueva cantidad existente
qs_total.update(total=s_total)
# Obteiene item id del tipo de cortador asi puede regresar a la pantalla del listado
pp = model.objects.filter(pk=pk).values('tipo')
ppp = pp.values_list('tipo', flat=True)
pk = ppp[0]
return HttpResponseRedirect(reverse('inventario:cortadores-list', args=(pk, )))
else:
# Redirect to fail page after POST
return HttpResponse('')
else:
form = updateForm()
return render(request, 'inventario/update.html', {'form':form})
这是我的摘要class在我的models.py
class Item(models.Model):
description = models.CharField(max_length=30,)
numero_parte = models.CharField(max_length=30)
proveedor = models.ForeignKey(Proveedor, on_delete=models.CASCADE)
cantidad_existente = models.PositiveIntegerField()
update = models.PositiveIntegerField(blank=True, default=0)
cantidad_minima = models.PositiveIntegerField()
precio_unitario = models.DecimalField(max_digits=7, decimal_places=2)
total = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
asignado_a = models.ForeignKey(Empleados, on_delete=models.CASCADE, blank=True, null=True)
anaquel = models.CharField(max_length=2, choices=ANAQUEL, blank=True, null=True)
posicion_en_x = models.CharField(max_length=2, blank=True, null=True)
posicion_en_y = models.CharField(max_length=2, blank=True, null=True)
activo = models.BooleanField()
class Meta:
abstract = True
def save(self,*args,**kwargs):
self.total = self.cantidad_existente * self.precio_unitario
super().save(*args,**kwargs)
这两个class继承自Item
class Cortadores(Item):
tipo = models.ForeignKey(Tipos_Cortadores,on_delete=models.CASCADE)
material = models.ForeignKey(Materiales, on_delete=models.CASCADE)
filos = models.CharField(max_length=5, choices=GABILANES)
diametro = models.ForeignKey(Diametros, on_delete=models.CASCADE)
longitud = models.ForeignKey(Longitud, on_delete=models.CASCADE)
desbaste = models.CharField(max_length=1, choices=DESBASTE)
class Meta:
verbose_name_plural = "Cortadores"
def get_absolute_url(self):
return reverse('inventario:cortadores-list', kwargs={'id': self.tipo.id})
def __str__(self):
return '%s %s %s %s %s %s' % ( str(self.tipo), str(self.material), str(self.filos), str(self.diametro),
self.longitud, self.desbaste
)
class Tornillos(Item):
tipo = models.CharField(max_length=10, choices=TIPO_TORNILLO)
paso = models.ForeignKey(Paso_Tornillo, on_delete=models.CASCADE)
material = models.ForeignKey(Materiales, on_delete=models.CASCADE)
longitud = models.ForeignKey(Longitud, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "Tornillos"
def get_absolute_url(self):
return reverse('inventario:lista-herramientas-mecanicas')#, kwargs={'pk': self.pk})
def __str__(self):
return '%s %s %s %s' % (str(self.tipo), str(self.paso), str(self.material), str(self.longitud))
我为我拥有的每种工具类型制作了一个 class。为简单起见,我只包括了这两个 class,而没有用大量代码填充 post。
如果您仍然可以更改 table 的设计,则可以使用您现在使用的 multi-table-inheritance instead of the abstract-base-class。
这意味着您将拥有一个模型 Item
(这将是一个实际的数据库 table),然后是从该模型继承的其他模型(它们的数据库 tables将只保留新字段,但不会重复任何字段)。
对于该更改,您只需从 Item.Meta
中删除 abstract = True
;您不需要更改模型的其他部分。当然,您将不得不再次删除 tables 和 运行 迁移(会破坏您当前的数据)。
正如我所说,只有当您仍然可以显着更改数据库 tables 时,这才是一个选项。
使用此设置,您可以直接查询 Item
模型的公共字段。您必须注意一些细微之处,但请阅读我链接的文档,看看它是否能解决您的问题。
伙计们,我想创建一个工具清单应用程序。
我有这种方法可以对所有工具类型执行完全相同的操作。我想知道的是如何使用此方法动态选择要使用的模型(也许如何将模型 class 作为参数传递)。
它目前仅适用于一种类型的工具。我的 models.py 有一个抽象模型,它包含所有工具的所有公共字段,然后是针对工具特定字段继承它的各种模型(e.i。立铣刀、钻头-钻头、钳子、螺丝刀等都继承了我的抽象模型的通用字段。
def calcular_nueva_cantidad(ce, up, get_link):
if get_link == 'incremento':
total = ce + up
else:
total = -(ce - up)
return total
def calcular_nuevo_total(nce, pu):
total = nce * pu
return total
# crea el formulario para la actualizacion de cantidad existente
class updateForm(forms.Form):
update = forms.IntegerField()
def actualizar_cantidad(request, pk, model ):
# trae de la base de datos el valor de la cantidad_existente
cantidad_existente = model.objects.filter(pk=pk).values('cantidad_existente')
c = cantidad_existente.values_list('cantidad_existente', flat=True)
ce = c[0]
# trae de la base de datos el valor de la precio_unitario
precio_unitario = model.objects.filter(pk=pk).values('precio_unitario')
p = precio_unitario.values_list('precio_unitario', flat=True)
pu = p[0]
# trae de la base de datos el valor de la total
qs_total = model.objects.filter(pk=pk).values('total')
if request.method =='POST':
form = updateForm(request.POST)
if form.is_valid():
# Obtiene el name de urls para el link segun sea el caso
get_link = resolve(request.path_info).url_name
get_linkwargs = resolve(request.path_info).kwargs
print(F'========>{get_link, get_linkwargs }<=========')
up = form.cleaned_data['update']
# Calcula el nuevo valor de cantidad existente
nce = calcular_nueva_cantidad(up, ce, get_link)
# Actualiza la nueva cantidad existente
cantidad_existente.update(cantidad_existente=nce)
# Calcula el nuevo valor de cantidad existente
s_total = calcular_nuevo_total(nce, pu)
# Actualiza la nueva cantidad existente
qs_total.update(total=s_total)
# Obteiene item id del tipo de cortador asi puede regresar a la pantalla del listado
pp = model.objects.filter(pk=pk).values('tipo')
ppp = pp.values_list('tipo', flat=True)
pk = ppp[0]
return HttpResponseRedirect(reverse('inventario:cortadores-list', args=(pk, )))
else:
# Redirect to fail page after POST
return HttpResponse('')
else:
form = updateForm()
return render(request, 'inventario/update.html', {'form':form})
这是我的摘要class在我的models.py
class Item(models.Model):
description = models.CharField(max_length=30,)
numero_parte = models.CharField(max_length=30)
proveedor = models.ForeignKey(Proveedor, on_delete=models.CASCADE)
cantidad_existente = models.PositiveIntegerField()
update = models.PositiveIntegerField(blank=True, default=0)
cantidad_minima = models.PositiveIntegerField()
precio_unitario = models.DecimalField(max_digits=7, decimal_places=2)
total = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
asignado_a = models.ForeignKey(Empleados, on_delete=models.CASCADE, blank=True, null=True)
anaquel = models.CharField(max_length=2, choices=ANAQUEL, blank=True, null=True)
posicion_en_x = models.CharField(max_length=2, blank=True, null=True)
posicion_en_y = models.CharField(max_length=2, blank=True, null=True)
activo = models.BooleanField()
class Meta:
abstract = True
def save(self,*args,**kwargs):
self.total = self.cantidad_existente * self.precio_unitario
super().save(*args,**kwargs)
这两个class继承自Item
class Cortadores(Item):
tipo = models.ForeignKey(Tipos_Cortadores,on_delete=models.CASCADE)
material = models.ForeignKey(Materiales, on_delete=models.CASCADE)
filos = models.CharField(max_length=5, choices=GABILANES)
diametro = models.ForeignKey(Diametros, on_delete=models.CASCADE)
longitud = models.ForeignKey(Longitud, on_delete=models.CASCADE)
desbaste = models.CharField(max_length=1, choices=DESBASTE)
class Meta:
verbose_name_plural = "Cortadores"
def get_absolute_url(self):
return reverse('inventario:cortadores-list', kwargs={'id': self.tipo.id})
def __str__(self):
return '%s %s %s %s %s %s' % ( str(self.tipo), str(self.material), str(self.filos), str(self.diametro),
self.longitud, self.desbaste
)
class Tornillos(Item):
tipo = models.CharField(max_length=10, choices=TIPO_TORNILLO)
paso = models.ForeignKey(Paso_Tornillo, on_delete=models.CASCADE)
material = models.ForeignKey(Materiales, on_delete=models.CASCADE)
longitud = models.ForeignKey(Longitud, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "Tornillos"
def get_absolute_url(self):
return reverse('inventario:lista-herramientas-mecanicas')#, kwargs={'pk': self.pk})
def __str__(self):
return '%s %s %s %s' % (str(self.tipo), str(self.paso), str(self.material), str(self.longitud))
我为我拥有的每种工具类型制作了一个 class。为简单起见,我只包括了这两个 class,而没有用大量代码填充 post。
如果您仍然可以更改 table 的设计,则可以使用您现在使用的 multi-table-inheritance instead of the abstract-base-class。
这意味着您将拥有一个模型 Item
(这将是一个实际的数据库 table),然后是从该模型继承的其他模型(它们的数据库 tables将只保留新字段,但不会重复任何字段)。
对于该更改,您只需从 Item.Meta
中删除 abstract = True
;您不需要更改模型的其他部分。当然,您将不得不再次删除 tables 和 运行 迁移(会破坏您当前的数据)。
正如我所说,只有当您仍然可以显着更改数据库 tables 时,这才是一个选项。
使用此设置,您可以直接查询 Item
模型的公共字段。您必须注意一些细微之处,但请阅读我链接的文档,看看它是否能解决您的问题。