Python 在外键模型中创建其他字段(Django查询)

Python 在外键模型中创建其他字段(Django查询),python,django,django-queryset,Python,Django,Django Queryset,models.py from django.db import models class person(models.Model): name = models.CharField(max_length=100, blank=true) characteristics = models.ManyToManyField(characteristics, default = '', on_delete=models.SET_DEFAULT) def __str__(self

models.py

from django.db import models

class person(models.Model):
    name = models.CharField(max_length=100, blank=true)
    characteristics = models.ManyToManyField(characteristics, default = '', on_delete=models.SET_DEFAULT)
    def __str__(self):
        return self.name

class characteristics(models.Model):
    name = models.CharField(max_length=100, blank=true)
    def __str__(self):
        return self.name
我和queryset有些麻烦。 我创造了三个人:吉姆,约翰,杰克。 然后创造4个特征:力量、敏捷、智慧、智慧 将吉姆与力量和敏捷联系起来(他强壮灵巧) 把约翰和智慧联系起来(他是个聪明人) 将杰克与力量、敏捷、智慧、智慧联系起来(他是各行各业的杰克)

输出如下所示:

Jim: strength, agility
John: wisdom, intelligence
Jack: strength, agility, wisdom, intelligence
是否有可能为这些特征增加价值? 例如:

Jim: strength=10 , agility=10
John: wisdom=10, intelligence=10
Jack: strength=9, agility=8, wisdom=8, intelligence=9
我认为,这些值需要存储在“person”表中。我可以在models.py中创建其他字段,但我的目标是在创建新角色时在“person”模型中创建其他字段

有一种方法可以在“person”模型中使用0…1000个空的int字段,然后为charlecteristics提供额外的数字(如id),然后将该特征id与“person”0…1000个空字段连接起来

from django.db import models

class person(models.Model):
    name = models.CharField(max_length=100, blank=true)
    characteristics = models.ManyToManyField(characteristics, default = '', on_delete=models.SET_DEFAULT)
    char0 = IntegerField(blank=True)
    ...
    char1000 = IntegerField(blank=True)
    def __str__(self):
        return self.name

class characteristics(models.Model):
    name = models.CharField(max_length=100, blank=true)
    additional_id = models.BigAutoField
    def __str__(self):
        return self.name

有什么优雅的方法可以解决我的问题吗?

我想你需要试试这样的方法:

    class characteristics(models.Model):
        id = models.AutoField(primary_key=True, )
        name = models.CharField(max_length=100)
        parameter = models.SmallIntegerField(default=0)
接下来,您可以执行以下操作:

Jim = person.objects.get(name = Jim)
jims_str = characteristics.objects.create(name = "strengh", parameter = 5)
jims_wisdom = characteristics.objects.create(name = "wisdom", parameter = 2)
Jim.characteristics.add(jims_str)
Jim.characteristics.add(jims_wisdom)
Jim.save()
我可能会错过一些细节,但主要的逻辑可能是这样的。不同的特性(好的做法是在Python中用大写字母Later命名类名)可能具有相同的名称,但具有唯一的PrimaryKey,并且将通过连接到Person模型。

方法2:
您可以编辑您的
人员
,如:

class Person(models.Model):
    id = models.AutoField(primary_key=True, )
    name = models.CharField(max_length=100)
    strength = models.ForeignKey('Strength', blank=True, null=True, on_delete=models.SET_NULL)
    agility= models.ForeignKey('Agility', blank=True, null=True, on_delete=models.SET_NULL)
    intelligence= models.ForeignKey('Intelligence', blank=True, null=True, on_delete=models.SET_NULL)
    wisdom= models.ForeignKey('Wisdom', blank=True, null=True, on_delete=models.SET_NULL)
接下来创建4个模型:
力量、敏捷、智慧、智慧

class Strength(models.Model):
        id = models.AutoField(primary_key=True, )        
        parameter = models.SmallIntegerField(default=0)
找到了4个解决方案

第一(我应该使用它,因为我没有足够的时间,也没有找到其他合适的方法):

在特征中创建新对象后,对象将获得额外的_id(从1开始)。 Lateron将特征与person.characteristicsX连接,其中(X=特征。附加_id)。 然后,我们可以调用object,并按characteristicsX(其中X=characteristics.additional_id)对特征进行排序

第二:

可能会导致问题,因为用户可以设置2个相同的特征。还有一种方法可以禁止它使用表单等

第三:

然后使用表单将值保存到person.characteristics字段中。这种方法仍然可以工作,但它需要按charecteristics.objects对TextField中的信息进行排序。这将需要一些时间来设置好它,但会工作得很棒

第四:
使用postgreSQL并存储数组。

我认为person表不是存储每个特征值的好地方。为什么它不应该和person\u id和characteristic\u id一起出现在多对多表中?如果您在多对多表中填写
,则您将始终知道每个人对每个指定特征的值。@T.Tokic这是个人数据吗?如果是这样的话,为什么我需要通过所有的数据库而不是仅仅一个“person”表来分离它呢?如果我要这样做,我需要从一开始就重构我的数据库。但这也是一种方式,thx。这也是一种方式,但每次我想创造新的特性时,我都需要手工在模型中创造。例如,如果我需要创建新的特征“构造”,我需要创建具有值的新模型,并通过外键将此模型添加到person。我的目标是允许用户亲自创建\选择特征并在特征中设置值。因此,这是我编写的第一个方法。并且“值”数据将存储在“特征”表中。以后,当我需要给有特征的人打电话时,需要对数据库进行更多的查询。此外,用户可能会在单词上出错,或者用自己的思维来称呼事物(例如:力量和力量,或者灵巧和敏捷)。为特征和特征值提供额外的模型==越来越多的查询,就像滚雪球一样。用户不需要有这么多的自由,否则他们会更打扰我。1)你说“当我需要给有个性的人打电话时,需要对数据库进行更多的查询”是什么意思?您应该有相同数量的查询-只需通过select_related()获取值即可。2) 如果你不想让用户犯“文字上的错误”,最好的方法就是提前定义所有可能的特征。可能会尝试在Django玩选择游戏。3) 您还可以尝试使用models.JSONField——它可以用JSON(实际上也是Python dict)1保存您的特征。使用这个简单的模型,查询量是相同的。就我而言,这将带来更多的麻烦而不是利润。2) 我不知道用户将使用多少特性,如果明天在2a.m,用户会要求我创建更多的模型吗?Choices与ForeignKey模型相同。3) 我需要让postgreSQL使用JSONField,postgreSQL有ArrayField,它可以包含成倍的值。我认为创建自定义字段比学习JSON和postgreSQL更容易。
models.py

from django.db import models
class person(models.Model):
    name = models.CharField(max_length=128, blank=False)
    characteristics = models.ManyToManyField(characteristics,
    null=True,
    on_delete=models.SET_NULL)
    characteristics1 = models.FloatField(blank=True, null=True) 
    ....   
    characteristics20 = models.FloatField(blank=True, null=True)

class characteristics(models.Model):
    name = models.CharField(max_length=100, blank=true)
    additional_id = models.BigAutoField
models.py

from django.db import models

class person(models.Model):
    name = models.CharField(max_length=128, blank=False)
    characteristics = models.ManyToManyField(characteristics,
    null=True,
    on_delete=models.SET_NULL)
    characteristics1_type = models.ForeignKey('characteristics', blank=True, null=True, on_delete=models.SET_NULL)
    characteristics1_value = models.FloatField(blank=True, null=True) 
    ....   
    characteristics20_type = models.ForeignKey('characteristics', blank=True, null=True, on_delete=models.SET_NULL)
    characteristics20_value = models.FloatField(blank=True, null=True) 

class characteristics(models.Model):
    name = models.CharField(max_length=100, blank=True)
models.py

from django.db import models
class person(models.Model):
    name = models.CharField(max_length=128, blank=False)
    characteristics = models.models.TextField(blank=True)

class characteristics(models.Model):
    name = models.CharField(max_length=100, blank=True)