多个模型类Django的可重用视图方法

时间:2018-07-09 20:29:56

标签: django django-models django-views django-urls

我想创建一个工具清单应用程序。

我有这种方法可以对所有工具类型做完全相同的事情。我想知道的是如何使用此方法动态选择要使用的模型(也许如何将模型类作为参数传递)。

它目前仅适用于一种工具。我的 models.py 有一个抽象模型,该模型具有所有工具的所有公共字段,然后有各种模型在工具特定的字段中继承该模型(例如,立铣刀,钻头,钳子,螺丝刀等都继承了)常见于我的抽象模型中。

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})

这是我的 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)

这两个类继承自 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))

我为自己拥有的每种工具类型创建了一个类。为了简单起见,我仅包括了这两个类,而没有用大量代码填充帖子。

1 个答案:

答案 0 :(得分:0)

如果您仍然可以更改表的设计,则可以使用multi-table-inheritance而不是现在使用的abstract-base-class

这意味着您将拥有一个模型Item(它将是一个实际的数据库表),然后拥有从该模型继承的其他模型(它们的数据库表将仅包含新字段,而不会重复任何字段)字段)。

对于该更改,您只需从abstract = True中删除Item.Meta;您无需更改模型中的其他零件。当然,您将不得不删除表并再次运行迁移(将破坏您的当前数据)。

正如我所说,这只是您仍然可以显着更改数据库表的一种选择。


使用此设置,您可以直接在Item模型中查询公共字段。您必须小心一些细微之处,但请阅读我链接的文档,看看它是否可以解决您的问题。