2013-09-12 5 views
0

Это ссылка на большой ответ Can I use JSON data to add new objects in Django?Создает ли метод setattr() временный объект?

Однако я особенно заинтригован, как работает этот компонент: член, _ = Member.objects.get_or_create (имя = self.name) Пожалуйста, посмотрите на контекст и заявление ниже.

class Member(models.Model): 
     def __unicode__(self): 
      return self.record 

     def was_published_recently(self): 
      return self.pub_date >= timezone.now() - datetime.timedelta(days=1) 
     was_published_recently.admin_order_field = 'pub_date' 
     was_published_recently.boolean = True 
     was_published_recently.short_description = 'Entered recently?' 

     record = models.CharField(max_length=200) 
     pub_date = models.DateTimeField('date') 


    class Data(models.Model): 

    member = models.ForeignKey(Member) 
    dob = models.CharField(max_length=200, blank=True, null=True) 
    event = models.CharField(max_length=200, blank=True, null=True) 
    description = models.CharField(max_length=200, blank=True, null=True) 
    gender = models.CharField(max_length=200, blank=True, null=True) 

    def save(self, *args, **kwargs): 

     **member, _ = Member.objects.get_or_create(name = self.name)** 
     # can update member here with other fields that relate to them 
     self.member = member 
     super(Data, self).save(*args, **kwargs) 


//---- 

     json = [{" Record": 12345, 
    "Name": "Joe", 
    "Event":" Initial task completed", 
    "TeamID": 12345, 
    "IndiviualID":"", 
    "Description":" Just a description", 
    "Date": "1/3/13 9:00"},{" Record": 5555, 
    "Name": "Jane", 
    "Event":" A different task completed", 
    "TeamID": 9999, 
    "IndiviualID":"", 
    "Description":" Just another description", 
    "Date": "1/13/13 6:00"}] 

     for item in json: 

      d = Data() 

      for k,v in item.iteritems(): 
       **setattr(d, k.lower(), v)** 

      d.save() 

Обратите внимание, что self.name технически доступ к имени переменной в моем объекте данных, которые в действительности имя переменной не существует в моем определении модели объекта данных. Итак, это ядро ​​моего вопроса: как работает этот код? Это заставило меня подумать, что есть какой-то временный объект данных, который фактически содержит Data.name (aka self.name), прежде чем он будет отброшен, поскольку он находится в представлении JSON данных, но не на моем объекте Data.

ответ

4

Нет, это не так, как это работает.

Объекты Python являются динамическими. Вы можете определить любые атрибуты, которые вам нравятся на них в любой момент. Неважно, выполняете ли вы setattr(d, "name", "foo") или d.name = foo, результат будет таким же: экземпляр d получает атрибут name, независимо от того, имел ли он его ранее или нет или нет в определении, указанном в нем.

Модели Django добавляют свой собственный специальный синтаксис для определения полей, которые они хранят в базе данных, но под ними они просто объекты Python, поэтому вы можете динамически определять дополнительные атрибуты на них столько, сколько хотите.

+0

Таким образом, вы можете добавить атрибуты к объекту Python, но, очевидно, вы не сможете добавить его в базу данных, если вы не сообщите о нем модели Django (т. Е. Определили ее). Правильно? Благодаря! Удивительное объяснение. – BluePython

+0

Да, это правильно. –

+0

Подробнее см. В разделе «Модель данных» (http://docs.python.org/2/reference/datamodel.html) в документах, но в основном, 'setattr (d,« name »,« foo »)' просто решает на 'd .__ dict __ [" name "] =" foo "'. (Вы можете настроить его для разных действий несколькими способами, но по умолчанию используется просто '__dict__'.) – abarnert

Смежные вопросы