2011-12-11 88 views
0

我正在制作游戏。玩家的库存持有武器。武器是武器模型的实例。当创建新武器时,从模板模型实例中随机选择武器模板。比所有字段都被复制来创建武器实例。要做到这一点我用这个函数:在Django中从另一个模型的实例创建模型实例,但不链接到原始实例源

class ItemModel(models.Model): 
    def fromTemplate(self, templateInstance): 
     if issubclass(type(self), type(templateInstance)): 
      for field in templateInstance._meta.fields: 
       setattr(self, str(field.name), getattr(templateInstance, field.name)) 
      self.pk = None 
      self.save() 
      for m2mField in templateInstance._meta.many_to_many: 
      setattr(self, m2mField.name, getattr(templateInstance, m2mField.name).all()) 

    class Meta: 
    abstract = True 

下面是模型的定义:

class WeaponTemplate(ItemModel): 
    def __unicode__(self): 
     return str(self.id) 
    type = models.CharField(max_length=100, choices = TYPE_CHOICES) 
    category = models.CharField(max_length=100, choices = CATEGORY_CHOICES) 
    group = models.CharField(max_length=100, choices = GROUP_CHOICES) 
    name = models.CharField(max_length=25) 
    level = models.IntegerField(default=1) 
    frequency = models.IntegerField(default = 100) 
    rarity = models.CharField(max_length=8, choices = RARITY_CHOICES) 
    multiplier = models.IntegerField() 
    buyCost = models.IntegerField() 
    sellValue = models.IntegerField(blank=True, null=True) 

class Weapon(WeaponTemplate): 
    def __unicode__(self): 
     return self.name 

现在我的问题是,“fromTemplate”功能,还增加了一个新的实例在模板模型。所以当我这样做时:

randomWeaponTemplate = random.choice(WeaponTemplate.objects.all()) 
newWeapon = Weapon() 
newWeapon.fromTemplate(randomWeaponTemplate) 
newWEapon.save() 

我在WeaonTemplate表中看到一个新条目。我应该如何修改我的代码以独立存储两个模型,以便在从武器模板创建新武器时,不会添加WeaponTemplate表?

+1

为什么不删除'self.save()''从方法fromTemplate'?或替换为'templateInstance.save()'? – danihp

+0

抱歉,fromTemplate方法中寂寞的self.save()会丢失几行代码。我希望这两个模型独立存储数据,templateInstance.save()如何让我更接近我的目标? –

回答

0

我认为你不应该在武器和武器模板之间使用继承,django将继承看作OneToOneRelationship。如果你想使你的代码更干,你可以尝试做事情的方式:

from django.db import models 
from django.db.models.manager import Manager 


class WeaponBase(models.Model): 
    def __unicode__(self): 
     return str(self.id) 

    name = models.CharField(max_length=25) 
    level = models.IntegerField(default=1) 
    frequency = models.IntegerField(default = 100) 
    multiplier = models.IntegerField() 
    buyCost = models.IntegerField() 
    sellValue = models.IntegerField(blank=True, null=True) 

    class Meta: 
     abstract = True 

class RandomManager(Manager): 
    def get_query_set(self): 
     return super(RandomManager, self).get_query_set().order_by('?')[0] 

class WeaponTemplate(WeaponBase): 
    objects = Manager() 
    random = RandomManager() 

class Weapon(WeaponBase): 
    @classmethod 
    def fromTemplate(cls, weaponTemplate): 
     w = Weapon() 
     for field in w._meta.fields: 
      setattr(w, str(field.name), getattr(weaponTemplate, field.name)) 
     return w 

+0

我喜欢它,但是如何确保新实例包含它所接收的模板中的所有字段,例如“如果issubclass(type(self),type(templateInstance)):” –

+0

请问您能解释我为什么需要这个。如果我清楚地看到整个图像,可能我可以帮助你更好。 正如我看到你做这个测试来检查你是否可以从模板创建一些东西。但在我的模型中,你总是可以做到这一点。也许我误解了一些东西? – Ilya

相关问题