在Django模型中将子链接到父

时间:2019-10-17 22:50:28

标签: django django-models django-queryset

我有一个地方模型:

public class MyClass: Java.Lang.Object
{
    private string Num { get; set; } = "";

    public MyClass() {}

    public MyClass(int? num)
    {
        Num = String.IsNullOrEmpty(num) ? "" : num;
    }

    public string GetNum()
    {
        return Num;
    }

    public override bool Equals(object other)
    {
        return Equals(other as MyClass);
    }

    public bool Equals(MyClass otherItem)
    {
        if (otherItem == null)
        {
            return false;
        }
        return otherItem.Num == Num;
    }

    public override int GetHashCode()
    {
        int hash = 19;
        hash = hash * 31 + (Num == null ? 0 : Num.GetHashCode());
        return hash;
    }
}

最初,我创建了一个地方来保存有关城市的信息,例如旧金山或纽约。

现在,我想创建一个名为Bar的新模型:

class Place(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    country = models.CharField(max_length=100, null=True, blank=True)
    postal_code = models.CharField(max_length=100, null=True, blank=True)
    region = models.CharField(max_length=1000, choices=REGION, null=True, blank=True)
    longitude = models.CharField(max_length=20, null=True, blank=True)
    latitude = models.CharField(max_length=20, null=True, blank=True)

    date_created = models.DateTimeField(_('date created'), default=timezone.now)
    date_modified = models.DateTimeField(_('date_modified'), auto_now=True)

我想将酒吧链接到Place模型中的特定城市。因此,我将继承的模型的一行与其父项链接在一起。我可以避免创建城市模型,而外键应该插入Bar吗?这可行吗?如果是这样,我该怎么办?

1 个答案:

答案 0 :(得分:0)

当您在parent_link=True中设置OneToOneField时,即使使用两个ORM,联接的模型也被视为同一模型,即使它们是两个单独的数据库表。

无需将Bar链接到特定的Place;您可以使用Bar模型同时创建Bar实例和Place实例:

bar = Bar.objects.create(name='Blackbird', city='San Fransisco', 
          country='US', date_inception='10-17-2019', ...
      )

根据您的评论,我猜您根本不想要这个。相反,您可能希望在ForeignKeyPlace模型之间建立Bar关系,因为 place (例如San Fransisco)可以有很多条形,但是只能有一个地方。

更新

根据我对您评论的理解,这是我的建议:

class PlaceMixin(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    longitude = models.CharField(max_length=20, null=True, blank=True)
    latitude = models.CharField(max_length=20, null=True, blank=True)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        latitude = self.latitude
        longitude = self.longitude
        do_stuff(latitude, longitude)
        super().save()

class Location(PlaceMixin):
    country = models.CharField(max_length=100, null=True, blank=True)
    postal_code = models.CharField(max_length=100, null=True, blank=True)
    region = models.CharField(max_length=1000, choices=REGION, null=True, blank=True)

class Bar(PlaceMixin):
    location = models.ForeignKey(Location, related_name='bars', on_delete=models.CASCADE)

class Store(PlaceMixin):
    location = models.ForeignKey(Location, related_name='stores', on_delete=models.CASCADE)

现在您可以同时访问PlaceLocation的经/纬度:

>>>location = Location.objects.create(name='San Fransisco', latitude=1, longitude=1)
>>>bar = Bar.objects.create(name='Blackbird', latitude=2, longitude=2, location=location)
>>>
>>>bar.latitude
2
>>>bar.location.latitude
1

要查询旧金山的所有酒吧,

location = Location.objects.select_related('Bar').get(name='San Fransisco')
bars = location.bars.all()