无法分配“ 9”:“ Characterweapons.weaponid”必须是“武器”实例

时间:2018-08-12 20:37:38

标签: python sql django django-models django-views

我一直在阅读与我类似的问题,但它们并没有帮助我。

尝试提交表单时出现此错误:

Cannot assign "9": "Characterweapons.weaponid" must be a "Weapons" instance.

这个“ 9”是我从表单中获得的武器的ID,因此非常好,但是当我尝试将其放入“ Characterweapons”表的“武器ID”列中时,就会出现错误。

models.py:

from __future__ import unicode_literals

from django.db import models


class Category(models.Model):
    categoryid = models.AutoField(db_column='CategoryID', primary_key=True)  # Field name made lowercase.
    categoryname = models.CharField(db_column='CategoryName', max_length=50, blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = True
        db_table = 'category'
    def __str__(self):
        return self.categoryname

class Characters(models.Model):
    characterid = models.AutoField(db_column='CharacterID', primary_key=True)  # Field name made lowercase.
    name = models.CharField(db_column='Name', unique=True, max_length=255)  # Field name made lowercase.
    level = models.IntegerField(db_column='Level')  # Field name made lowercase.
    credits = models.IntegerField(db_column='Credits')  # Field name made lowercase.

    class Meta:
        managed = True
        db_table = 'characters'

    def __str__(self):
        return '%s %s %s' % (self.name, self.level, self.credits)

class Weapons(models.Model):
    weaponid = models.AutoField(db_column='WeaponID', primary_key=True)  # Field name made lowercase.
    weaponname = models.CharField(db_column='WeaponName', unique=True, max_length=255)  # Field name made lowercase.



    class Meta:
        managed = True
        db_table = 'weapons'

    def __str__(self):
        return '%s %r' % (self.weaponname, self.weaponid)       

class Characterweapons(models.Model):
    characterid = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID')  # Field name made lowercase.
    weaponid = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True)  # Field name made lowercase.
    categoryid = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True)  # Field name made lowercase.
    quantity = models.IntegerField(db_column='Quantity', blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = True
        db_table = 'characterweapons'
    def __str__(self):
        return '%s' % (self.quantity)



class DjangoMigrations(models.Model):
    app = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    applied = models.DateTimeField()

    class Meta:
        managed = True
        db_table = 'django_migrations'

我不知道这是否是FK问题,PK ...不知道,我也找不到解决问题的信息...

views.py :(必须存在错误的地方):

def submission(request):

    print("Registered successfully")
    Name = request.POST["Name"]
    Level = request.POST["Level"]
    Credits = request.POST["Credits"]
    Mainhand = request.POST["Mainhand"]
    Offhand = request.POST["Offhand"]

    info = Characters(name=Name,level=Level,credits=Credits)
    info.save()
    mh=
    infomh = Weapons.objects.values_list('weaponid',flat=True)
    a=0;
    for a in infomh:
        if a == Mainhand:
            a = Mainhand;

    print("a: ")
    print(a)
    print("Mainhand")
    print(Mainhand)
    print("infmh:")
    print(infomh)

    charid = Characters.objects.latest('characterid')
    info_mh = Characterweapons(characterid=charid,categoryid=1,weaponid=a)
    info_mh.save()
    #info_oh =  Characterweapons(characterid=charid,weaponid=9,categoryid=2)
    #info_oh.save()



    return return_charnames(request) 

通过这些打印,我确保我的武器ID的值正确无误。 我还想指出,“武器”表中存在“武器”列中的value = 9。 谢谢大家。

2 个答案:

答案 0 :(得分:0)

您在模型Characterweapons中的外键武器ID不仅是其ID,而且是武器实例。 从该ID中查询对象并进行分配。

答案 1 :(得分:0)

我认为您最好先修复模型。在Django中,ForeignKey从概念上说是对您引用的对象的引用,而不是id。当然,它作为ID存储在数据库中,但这是您不应该在意的层。

因此,我建议您先将weaponid之类的字段重命名为weapon

class Characterweapons(models.Model):
    character = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID')
    weapon = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True)
    category = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True)
    quantity = models.IntegerField(db_column='Quantity', blank=True, null=True)

    # ... 

现在,如果您用名称ForeignKey构造一个fieldname,Django实际上会引入两个字段:fieldname,就像前面所说的那样,它指向模型对象的引用。引用ForeignKey,并使用字段fieldname_id存储该对象的id(主键)。因此,这两个字段的作用就像“双胞胎”。

然后我们可以像这样重写submission视图:

def submission(request):
    print("Registered successfully")
    name = request.POST["Name"]
    level = request.POST["Level"]
    credits = request.POST["Credits"]
    mainhand = request.POST["Mainhand"]
    offhand = request.POST["Offhand"]

    info = Characters.objects.create(name=name, level=level,credits=credits)
    if Weapons.objects.filter(weapon_id=mainhand).exists():
        a = mainhand

    info_mh = Characterweapons.objects.create(
        character_id=info.pk,
        category_id=1,
        weapon_id=a
    )
    return return_charnames(request)

在上面我也做了一些重构:

  1. 在Python中,函数中的变量通常具有小写名称;
  2. 您不需要遍历weapon_id,可以使用EXISTS查询,该查询通常更快;
  3. 您可以使用obj.save()来代替先构建模型实例,然后再Model.objects.create(..)来构建它;
  4. 您可能不想获取latest(..)的值,而是使用pk对象的info,因为这是我们构造的对象,此外,如果没有定义的顺序(如此处),该顺序可以是数据库喜欢的任何顺序,而不是最新添加的顺序。

您可能仍需要重写硬编码的标识符(例如a=1category_id=1,因为这些对象很可能在数据库中存在)。 / p>