I'm making a game. The player's inventory holds weapons. The weapons are instances of the Weapon model. When a new weapon is created a weapon template is selected at random from the Template model instances. Than all fields are copied to create the weapon instance. To do so I use this function:
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
Here is the models definition:
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
Now my problem is that the "fromTemplate" function also adds a new instance in the template model. So when I do this:
randomWeaponTemplate = random.choice(WeaponTemplate.objects.all())
newWeapon = Weapon()
newWeapon.fromTemplate(randomWeaponTemplate)
newWEapon.save()
I see a new entry in the WeaonTemplate table. How should I modify my code to make the two models independently stored so that when a new weapon is created from a weaponTemplate, no addition is made to the WeaponTemplate table?
I think you should not use inheritance between weapon and weapontemplate, django treats inheritance as OneToOneRelationship. If you want to make your code more DRY you may try to make things that way:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.