2014-12-02 77 views
0

我想重构模型中的一些代码,因为它有点乱。我有几个模型。Django多个相似的模型

class Part(models.Model): 
class Category(models.Model): 
class Labor(models.Model): 

依此类推,总共七个。我为他们生成ID。对于它的部分是:

def save(self, *args, **kwargs): 
    if not Part.objects.count(): 
     latest = 'XXX00000' 
    else: 
     latest = Part.objects.all().order_by('-par_id')[0].par_id 
    self.par_id = "PAR" + str(int(latest[3:]) + 1).zfill(5) 
    super(Part, self).save(*args, **kwargs) 

它和其他类非常相似。只有班级名称正在更改,三个字母标识和参数order_by。我想知道我该怎么做干。因为它应该以某种方式缩短每个类的7行代码。

我想知道也许创建BaseModel类继承它,并以某种方式改变只提到的东西。我想获得一些指导,我该如何做得更好。

编辑:

class Part(models.Model): 
    par_id = models.CharField(primary_key=True, unique=True, max_length=9, blank=False) 
    par_name = models.CharField(max_length=50) 

    def save(self, *args, **kwargs): 
     if not Part.objects.count(): 
      latest = 'XXX00000' 
     else: 
      latest = Part.objects.all().order_by('-par_id')[0].par_id 
     self.par_id = "PAR" + str(int(latest[3:]) + 1).zfill(5) 
     super(Part, self).save(*args, **kwargs) 


class Category(models.Model): 
    cat_id = models.CharField(primary_key=True, unique=True, max_length=9) 
    cat_name = models.CharField(max_length=50) 

    def save(self, *args, **kwargs): 
     if not Category.objects.count(): 
      latest = 'XXX00000' 
     else: 
      latest = Category.objects.all().order_by('-cat_id')[0].cat_id 
     self.cat_id = "CAT" + str(int(latest[3:]) + 1).zfill(5) 
     super(Category, self).save(*args, **kwargs) 

这是两个O我的班。

回答

1

创建class BaseModel(models.Model):和copypaste您save方法有,但self.__class__取代Part,例如

class BaseModel(models.Model): 
    # some fields here 

    class Meta: 
     abstract = True 

    def save(self, *args, **kwargs): 
     first_declared_field = self.__class__._meta.fields[1].name 

     if self.__class__.objects.count(): 
      latest = getattr(self.__class__.objects.order_by('-' + first_declared_field)[0], first_declared_field) 
     else: 
      latest = 'XXX00000' 


     field_value = first_declared_field.name.split('_')[0].upper() + str(int(latest[3:]) + 1).zfill(5) 
     setattr(self, first_declared_field, field_value) 

     super(BaseModel, self).save(*args, **kwargs) 

class SomeChildModel(BaseModel): 
    pass 
+0

我添加了我原来的帖子一些更多的信息。而你的方法适合这个,但有一点小事。对于每个班级,我可以使用我的数据更改kwargs,例如在order_by中,因为它是字符串。如何将par_id字段更改为另一个? – user84471 2014-12-03 12:53:27

+0

您可以获得字段列表,以便在模型self.__ class __._ meta.fields中声明它们,但是'self .__ class __._ meta.fields [0]'是id,所以您需要'... [1]' – madzohan 2014-12-03 15:32:19

+0

“PAR”或“CAT”你可以使用像这样的'self .__ class __._ meta.fields [1] .name.split('_')[0] .upper()' – madzohan 2014-12-03 15:36:22

2

继承绝对是一个好主意。

你没有给出关于模型的很多信息。因此,继承模型有两个主要选项:

A)使用可容纳常用字段和一些常用方法的AbstractModel。然后根据需要使用子模型来扩展字段和方法。下面是来自Django文档的例子:

from django.db import models 

class CommonInfo(models.Model): 
    name = models.CharField(max_length=100) 
    age = models.PositiveIntegerField() 

    class Meta: 
     abstract = True 

class Student(CommonInfo): 
    home_group = models.CharField(max_length=5) 

B)如果你只在继承或扩展你的模型的行为的部件(例如用于生成的ID)的不同方法感兴趣,代理模式是一个更好的选择。看看文档:https://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models

下面是来自Django文档取一个例子:

from django.db import models 

class Person(models.Model): 
    first_name = models.CharField(max_length=30) 
    last_name = models.CharField(max_length=30) 

class MyPerson(Person): 
    class Meta: 
     proxy = True 

    def do_something(self): 
     # ... 
     pass