如何通过装饰器在Django上预先填充ForeignKey中的字段?

时间:2017-08-15 08:15:39

标签: python django

假设我的模型在Django 1.11&中有3个类。 Python3.5:

第1课:

class City(models.Model):
    country = models.ForeignKey(Country)
    name = models.CharField(max_length=255)
    latitude = models.DecimalField(max_digits=15, decimal_places=10)
    longitude = models.DecimalField(max_digits=15, decimal_places=10)

    def __str__(self):
        return self.name

第2课:

class Profile(AbstractUser):
    username = models.ForeignKey(User, max_length=100, blank=False, unique=True)
    address = models.CharField(max_length=255, blank=False)
    city = models.ForeignKey(City, on_delete=models.CASCADE, related_name="city_set", max_length=100, blank=False, null=True)
    country = models.CharField(max_length=255, blank=False)
    birthplace = models.ForeignKey(City, on_delete=models.CASCADE, related_name="birthplace_set", max_length=100, blank=False, null=True)
    latitude = models.DecimalField(max_digits=15, decimal_places=10)
    longitude = models.DecimalField(max_digits=15, decimal_places=10)    

    def __str__(self):
        return self.username

    @property
    def country(self):
        if not self.city:
            return False
        else:
            negara = City.objects.get(name=self)
            return negara.country

    @property
    def latitude(self):
        if not self.birthplace:
            return False
        else:
            lat = City.objects.get(latitude=self)
            return lat.latitude

    @property
    def longitude(self):
        if not self.birthplace:
            return False
        else:
            lnt = City.objects.get(longitude=self)
            return lnt.longitude

第3课:

        string yourJsonString = @"{  ""post_id"":13,  ""thread_id"":9,  ""user_id"":1,  ""username"":""Username"",  ""post_date"":1496439611,  ""message"":""testzilla - 2133746943A9"",  ""ip_id"":698,  ""message_state"":""visible"",  ""attach_count"":0,  ""position"":0,  ""likes"":0,  ""like_users"":""a:0:{}"",  ""warning_id"":0,  ""warning_message"":"""",  ""last_edit_date"":1496476199,  ""last_edit_user_id"":0,  ""edit_count"":9,  ""node_id"":34,  ""title"":""Test"",  ""tags"":""a:0:{}"",  ""node_title"":""test node"",  ""node_name"":null,  ""message_html"":""testzilla - 2133746943A9"",  ""absolute_url"":""url""}";
        string value = System.Text.RegularExpressions.Regex.Match(yourJsonString,@"""message"":(.+?),").Groups[1].Value.Replace(@"""","");
        MessageBox.Show(value);

我的问题是:

  1. 如何从城市的属性(来自City的班级的ForeignKey)获取和预填充/填充国家/地区属性在Profile的类中?我试图通过使用@property装饰器来获取它,但我得到 nothing 值。
  2. 我可以将同一个类(来自City的类)用于一个类(到Profile的类)中的ForeignKey字段两次吗?在这种情况下是城市&出生地属性,然后重复我上面的问题为纬度和&来自出生地属性的经度属性。

1 个答案:

答案 0 :(得分:1)

填充这些字段和@property调用的目的是什么? 我宁愿使用这样的直接电话:

    person.city.country.name
    person.city.longitude
    person.city.latitude

它也适用于经度和纬度属性。但是,如果你需要一个预先填充的CharField,你可以在save()方法中这样做:

    Class Person(models.Model):
    ...
    def save(self, *args, **kwargs):
      self.country = self.city.country.name
      self.longitude = self.city.country.name
      self.latitude = self.city.country.name
      super(Person, self).save(*args, **kwargs)

是的,您可以根据需要使用尽可能多的ForeignKey字段。