Catma Catma - 10 months ago 57
Python Question

Using setattr() to update an object instance

I have a model class which has an attribute that refers to django DB objects. I would like to change this attribute using a single view with setattr() which I use to make changes to any attributes for this object.

The problem is, I can't seem to pass an object instance through the stack. I'm not sure if I can even use setattr() for this. Actually I'm not even sure if the problem is with my attempted use of setattr() or something else - please let me know!

Error on POST attempt:

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 %}


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


//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(""+dollhouseid, {
type: 'POST',
data: {
dh_background: dh_background,
console.log("The request is complete!");
window.location = "";
.fail(function() {
console.log("Sorry, there was a problem!");

Answer Source

You are passing the object id in the POST variable, not the actual object itself (you can't do it anyway). Either change the following part

data: {
    dh_background: dh_background,


data: {
    dh_background_id: dh_background,

or get the object instance using the id in your view code.