2016-11-29 4 views
1

У меня есть класс модели, который имеет атрибут, который ссылается на объекты DB django. Я хотел бы изменить этот атрибут, используя один вид с setattr(), который я использую для внесения изменений в любые атрибуты для этого объекта.Использование setattr() для обновления экземпляра объекта

Проблема в том, что я не могу передать экземпляр объекта через стек. Я не уверен, могу ли я использовать setattr() для этого. На самом деле я даже не уверен, что проблема связана с попыткой использования setattr() или чего-то еще - сообщите мне!

Ошибка при попытке POST:

ValueError at /dollhouseupdate/1 
Cannot assign "u'Citadel'": "Dollhouse.dh_background" must be a "Background" instance. 

Модель:

class Dollhouse(models.Model): 
    dollhouse_name = models.CharField(max_length=100) 
    user = models.ForeignKey(User) 
    dh_background = models.ForeignKey(Background) 
    def __str__(self): 
     return self.dollhouse_name 

Шаблон:

<select id="background-select"> 
     <option value="null">Change Background</option> 
     {% for background in background_objects %} 
     <option value="{{ background }}">{{ background.bg_name }} </option> 
     {% endfor %} 
    </select> 

Вид:

def dollhouseupdate(request, dollhouseid): 
    if request.method == 'POST': 
     workingdollhouse = Dollhouse.objects.get(id=dollhouseid) 
     if request.POST.get('erase') == "true": 
      workingdollhouse.delete() 
      return HttpResponse("Dollhouse deleted!") 
     else: 
      data = (request.POST).dict() 
      for key, value in data.items(): 
       setattr(workingdollhouse, key, value) 
      workingdollhouse.save() 
      return HttpResponse("Dollhouse {} saved!".format(workingdollhouse.dollhouse_name)) 

Javascript:

//change dollhouse background 
$("#background-select").change(function() { 
    if($("#background-select").val() != null) { 
     var dollhouseid = workingDollhouse; 
     var dh_background = $("#background-select").val() 
     console.log("changing background to " + dh_background); 
     $.ajax("http://127.0.0.1:8000/dollhouseupdate/"+dollhouseid, { 
      type: 'POST', 
      data: { 
       dh_background: dh_background, 
      } 
     }) 
     .done(function(response){ 
      console.log("The request is complete!"); 
      console.log(response); 
      window.location = "http://127.0.0.1:8000/"; 
     }) 
     .fail(function() { 
      console.log("Sorry, there was a problem!"); 
     }) 
    }; 
}); 

ответ

0

Вы передаём идентификатор объекта в переменной POST, а не сам объект (вы не можете сделать это в любом случае). Либо измените следующую часть

data: { 
    dh_background: dh_background, 
} 

в

data: { 
    dh_background_id: dh_background, 
} 

или получить экземпляр объекта, используя идентификатор в вашем представлении кода.

+0

Спасибо, это самый простой ответ и сохраняет использование setattr() для всех атрибутов. Я ранее пробовал это, используя «dh_background.id» вместо «dh_background_id», и он не обновлялся правильно. – Catma

0

Как сказано в сообщении об ошибке, атрибут Dollhouse.dh_background должен быть экземпляром модели Background. Вы пытаетесь установить его значение для объекта другого типа; Я думаю, что текстовая строка.

type(u'Citadel') is Background # False 

Вместо этого, вам нужно поставить некоторые СМАРТС в поле зрения, так что Background экземпляры извлекаются любым ключом у вас есть; затем установите для этого экземпляра атрибут Dollhouse.dh_background.

if name == 'background': 
    background_code = post_args[name] 
    background = Background.objects.get(code=background_code) 
    workingdollhouse.dh_background = background 

Поскольку разные аргументы POST относятся к разным полям, вам необходимо знать, к чему относится каждый, и относиться к ним по-разному. Простой «setattr для каждого» не будет работать.