0

I just started learing a django and have a that problem:

I wrote a heroes creator. Each hero has a name, nickname, race, profession and the integers values like: strength, mana and HP.

Code of model.py:

class Hero(models.Model):

    def statsRandomizer():
        str_random = random.randint(1,20)
        mana_random = random.randint(1,100)
        HP_random = random.randint(1,30)
        result = str_random
        return result

    RACES = {
    ("None", "None"),
    ("Human", "Human"),
    ("Elf", "Elf"),
    ("Dwarf", "Dwarf"),
    ("Ogre", "Ogre"),
    ("Hobbit", "Hobbit"),
    ("Gnome", "Gnome"),
    }


    user        = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL)

    name        = models.CharField(max_length=30)
    nickname    = models.CharField(max_length=30)
    race        = models.CharField(default=0, choices=RACES, max_length = 30)
    profession  = models.CharField(max_length=30)

    #To do ogarnięcia bo nie działa.
    slug        = models.SlugField(unique=True)

    strength    = models.PositiveSmallIntegerField()
    mana        = models.PositiveSmallIntegerField()
    HP          = models.PositiveSmallIntegerField()

    level       = models.PositiveSmallIntegerField(default = 0)



    def get_absolute_url(self):
        return f"/heroes/{self.slug}/"

    def get_edit_url(self):
        return f"/heroes/{self.slug}/edit/"

    def get_delete_url(self):
        return f"/heroes/{self.slug}/delete/"

As u can see, I wrote a simple method to randomize value. It's returning only strength for a test. What's a problem?

If I change my code to:

strength    = models.PositiveSmallIntegerField(default=statsRandomizer())
mana        = models.PositiveSmallIntegerField(default=statsRandomizer())
HP          = models.PositiveSmallIntegerField(default=statsRandomizer())

in form I see generated numbers, and I can create hero, but if I refresh it and want create second, I got same numbers. They are changed when I resave code in Atom.

And what is expected result? Can I repair that function to generate different numbers for each new hero?

For sure I attaching my forms:

from django import forms
from .models import Hero
import random

class HeroCreateForm(forms.Form):

    name        = forms.CharField()
    nickname    = forms.CharField()
    race        = forms.CharField()
    profession  = forms.CharField()

    #To do ogarnięcia bo nie działa.
    slug        = forms.SlugField()

    strength    = forms.IntegerField()
    mana        = forms.IntegerField()
    HP          = forms.IntegerField()




class HeroCreateModelForm(forms.ModelForm):
    class Meta:
        model = Hero
        fields = ['name', 'nickname', 'race', 'profession', 'strength', 'mana', 'HP' ]


    def clean_name(self, *args, **kwargs):
        instance = self.instance
        name = self.cleaned_data.get('name')
        qs = Hero.objects.filter(name__iexact=name) # iexact - lovercase/upper unique check
        if instance is not None:
            qs = qs.exclude(pk=instance.pk) #id = instance Pk = primary key
        if qs.exists():
            raise forms.ValidationError("This name is already exist! Please change it to unique one.")
        return name

It's more than sure that I haven't enough knowlage about django, so what should I learn to better handling with that problems in the future?

1 Answer 1

1
strength    = models.PositiveSmallIntegerField(default=statsRandomizer())
mana        = models.PositiveSmallIntegerField(default=statsRandomizer())
HP          = models.PositiveSmallIntegerField(default=statsRandomizer())

Function statsRandomizer run when your start the application

Try without ()

strength    = models.PositiveSmallIntegerField(default=statsRandomizer)
mana        = models.PositiveSmallIntegerField(default=statsRandomizer)
HP          = models.PositiveSmallIntegerField(default=statsRandomizer)
Sign up to request clarification or add additional context in comments.

3 Comments

WoW! That simple and it's works! Thank u :) So if I using call method I use it only when program starts, and without () I got dynamic changes?
Yes. default=func() evaluates a function call at Model definition time and the result gets used as the default for all instantiations. default=func saves the function itself as the default, and since it's a callable, it gets called every time an object gets instantiated and a default is needed.
Awesome, that's very usefull information for me. Thank u!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.