2014-12-02 26 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