簡體   English   中英

Django ForeignKey接受兩種模型

[英]Django ForeignKey accept two models

我正在使用Django處理這個大項目,並且我必須更新數據庫。 我必須添加另一個表,以后將替換另一個表。

因此,我想在模型中添加一個可能性,使我可以在其中擁有舊模型或新模型。

這是舊模型的代碼:

class Harvests(models.Model):
    ident_culture = models.IntegerField(primary_key=True)
    intitule_culture = models.CharField(max_length=50, blank=True)
    nom_fertiweb = models.CharField(max_length=50, blank=True, null = True)
    affichage_quintaux_tonne = models.CharField(max_length=1, 
                choices=RENDEMENT_CHOICES, default = 'T')
    type_culture = models.ForeignKey("TypeCulture", null=True)
    slug = models.SlugField(null=True, blank=True)
    image = models.ImageField(upload_to = 'images_doc_culture/', 
                  null=True, blank = True)
    affichage = models.BooleanField(default = True)

    class Meta:
        verbose_name = "Liste - Culture"
        verbose_name_plural = "Liste - Cultures"
        ordering = ['intitule_culture']

    def __str__(self):
        return self.intitule_culture

    def label(self):
        return self.intitule_culture or ''

    @classmethod
    def get_choices(cls):
        choices = [('', corp.EMPTY_CHOICE_LBL)]
        c_category_lbl, c_category = '', []
        for item in cls.objects.all():
            choices.append((item.pk, item.intitule_culture))
        return choices

還有我創建的新代碼:

class Crops(models.Model):
    intitule_culture = models.CharField(max_length=75, blank=True)
    affichage_quintaux_tonne = models.CharField(max_length=2, 
                choices=RENDEMENT_CHOICES, default = 'T')
    type_culture = models.ForeignKey("TypeCulture", null=True)
    ident_culture = models.IntegerField(primary_key=True)
    affichage = models.BooleanField(default = True)
    id_marle = models.IntegerField(null=True)

    class Meta:
        verbose_name = "Liste - Culture 2019"
        verbose_name_plural = "Liste - Cultures 2019"
        ordering = ['intitule_culture']

    def __str__(self):
        return self.intitule_culture

    def label(self):
        return self.intitule_culture or ''

    @classmethod
    def get_choices(cls):
        choices = [('', corp.EMPTY_CHOICE_LBL)]
        c_category_lbl, c_category = '', []
        for item in cls.objects.all():
            choices.append((item.pk, item.intitule_culture))
        return choices

我想在此模型中接受兩種現場culture模型:

class CompanyHarvest(models.Model):
    company = models.ForeignKey('corp.Company', verbose_name='Exploitation',
                related_name ='cultures')
    culture = models.ForeignKey(Harvests, verbose_name ='Culture')
    precision = models.CharField(max_length=255, blank=True)
    saison_culture = models.CharField(max_length=1, choices=SAISON_CHOICES, 
                      default = 'P')

    class Meta:
        verbose_name = "Expl. - Culture"
        verbose_name_plural = "Expl. - Cultures"
        unique_together = ('company', 'culture', 'precision', 'saison_culture')

    def __str__(self):
        return str(self.culture) + ' ' + self.precision + \
            ' ' + str(self.get_saison_culture_display() )

    @property
    def slug(self):
        return "_".join([slugify(str(self.culture or '')),
                                      slugify(str(self.precision or ''))]
                                      )

我是Django的新手,有人可以幫助我嗎? (^ - ^)

這是不可能的-至少不是這樣。 這不是Django的限制,而是SQL的限制,外鍵不能引用一個表或另一個表。

一個可能的簡單解決方案是在CompanyHarvest中擁有兩個外鍵-每個舊模型和新模型都具有一個外鍵,每個外鍵都具有blank=True et default=None ,但是它很快就會使所有客戶端代碼變得一團糟(所有代碼都使用CompanyHarvest )。

更好的解決方案是只保留現有模型(向其中添加任何新字段/功能並最終隱藏陳舊的字段/功能),或者將所有舊模型記錄遷移到新模型(可以與簡單的“兩個外鍵”結合使用)解決方案,因此您可以根據需要將舊表和記錄保留為存檔)。

另外-完全無關,但是-這是:

@classmethod
def get_choices(cls):
    choices = [('', corp.EMPTY_CHOICE_LBL)]
    c_category_lbl, c_category = '', []
    for item in cls.objects.all():
        choices.append((item.pk, item.intitule_culture))
    return choices

1 /應該在管理器上定義(參見https://docs.djangoproject.com/en/2.1/topics/db/managers/#adding-extra-manager-methods

2 /應該使用.values() queryset編寫(這會在沒有充分理由的情況下保存在數據庫查詢和構建完整的實例中):

for item in cls.objects.values("pk", "intitule_culture"):
    choices.append(item)

3 /,並且很有可能在調用代碼中被ModelChoiceField替換(我必須看看它的用法)。

哦,是的:如果您允許在文本字段中使用空格,則很可能要強制將空字符串設置為默認值,這樣,在沒有給出任何值的情況下,您就不會遇到兩種可能(且不兼容)的情況(sql NULL和空字符串)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM