使用表单更新django中的模型属性

时间:2015-06-11 15:42:38

标签: python django django-models

我正在尝试更新django应用中的模型字段。应用程序是这样的,有两个模型,项目和承包商。和他们的关系就像每个项目可以分配多个承包商,每个承包商可以处理多个项目......项目和承包商都与客户模型相关联..my models.py:

class UserProfile(models.Model):    ## the client is the user
   user=models.OneToOneField(User)
   def __unicode__(self):
   return self.user.username

class Contractor(models.Model): ##unhired contractors
   name=models.CharField(max_length=128)
   url=models.URLField()
   bill_rate=models.IntegerField(default=0)
   slug=models.SlugField(unique=True)
   def save(self, *args, **kwargs):
   self.slug=slugify(self.name)
   super(Contractor, self).save(*args, **kwargs)
   def __unicode__(self):
        return self.name

class Project(models.Model):
   contractor=models.ManyToManyField(Contractor, null=True)
   client=models.ForeignKey(UserProfile, null=True)
   title=models.CharField(max_length=128)
   slug=models.SlugField(unique=True)
   def save(self, *args, **kwargs):
       self.slug=slugify(self.title)
       super(Project, self).save(*args, **kwargs)
   def __unicode__(self):
       return self.title

和forms.py是:

class ProjectForm(forms.ModelForm):
    title=forms.CharField(max_length=128)
    slug=forms.CharField(widget=forms.HiddenInput(), required=False)
    class Meta:
       model=Project
       fields=('title','contractor')

class ContractorForm(forms.ModelForm): ##the contractor first register itself separately and is later added to the project while a project is been created
    name=forms.CharField(max_length=128, help_text="Please enter your name or your firm's name: ")
    bill_rate=forms.IntegerField(initial=0, help_text="Please enter your Bill rate")
    url=forms.CharField(max_length=128, help_text="Please enter your web-details: ")
    slug=forms.CharField(widget=forms.HiddenInput(), required=False)
    class Meta:
       model=Contractor
       fields=('name','bill_rate','url',)

以下是我正在尝试更新承包商属性的视图:

  def addContractorToUnaddedProjects(request):
     if request.method=="POST":
        project=ProjectForm(request.POST)
        if project.is_valid():
           project.save(commit=True)
        else:
           print project.errors
     else: 
       project=ProjectForm()
    return render(request, 'keeper/addContractorToUnaddedProject.html', {'form':update,})

因此,每当我尝试运行此代码而不是仅更新承包商字段时,就会创建一个全新的项目...更新项目的新承包商我将目前没有承包商的项目页面指向“addnewcontractor”页面&在那里我使用项目形式,但不是使用标题和承包商两者,我只是为承包商领域输入..我在这里做错了什么?

这是我用来更新已经创建项目的承包商的html代码:

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Add Contractor{% endblock %}
{% block body_block %}
<h1>Add a Contractor from our available Contractors!!</h1>
<form id="add_contractor_unadded" method="post" action="/keeper/addContractorToUnaddedProject/">
{% csrf_token %}
    <strong><h4>Please select a contractor: {{ form.contractor }}</h4></strong>
<input type="submit" name='submit' value="ADD" />
</form>
<h2><a href="/keeper/dashboard/">Home</a></h2>
{% endblock %}

2 个答案:

答案 0 :(得分:2)

你说&#34;每个项目都可以分配多个承包商&#34;但这不是你的模型如何运作 - 它允许每个项目的单个承包商:

class Project(models.Model):
    contractor=models.ForeignKey(Contractor, null=True)

ForeignKey如果是一对多关系 - 这里项目有零个或一个承包商,而承包商有零个,一个或多个项目。

如果你想在每个项目中拥有许多承包商,你必须使用多对多的关系,这在Django中使用ManyToManyField构建:

class Project(models.Model):
    contractors = models.ManyToManyField(Contractor, null=True)

现在以您的观点......好吧,怎么说......这完全是胡说八道。

首先,您使用ProjectForm而未向其传递Project个实例 - 这是创建新Project的方法(使用form.save()而不是Project。 t call),但不能编辑现有的。如果您要编辑现有的Project,请获取您的old_contractor = Project.objects.get(contractor='contractor') 实例并将其传递给表单(如模型所记录的那样)。

然后你有这个四重废话:

old_contractor = Project.objects.get(contractor__name='contractor')

这是行不通的......至少它应该是

Project

这仍然是一个三重废话:

  1. 您为对象命名&#39; old_contractor&#39;但它是ObjectDoesNotExist
  2. 为了这个工作,你必须有一个名为&#34;承包商的承包商&#34;并且必须有一个项目(否则会出现MultipleObjectsReturnedsave()错误
  3. 然后,您将在表单中选择承包商更新此项目。
  4. FWIW,没有一次机会代码会创建一个新项目,因为您调用表单的import flash.media.StageWebView; import flash.events.MouseEvent; import flash.events.Event; var _webView:StageWebView = new StageWebView(); btnmap.addEventListener(MouseEvent.MOUSE_UP, addWebView); function addWebView(e:MouseEvent):void { _webView.viewPort = new Rectangle(0, 170, 480,510); _webView.stage = this.stage; _webView.loadURL("https://goo.gl/maps/b6lMB"); btnclosemap.visible =true; btnclosemap.addEventListener(MouseEvent.CLICK, closeWebView); } function closeWebView(e:MouseEvent):void { _webView.stage = null; _webView.dispose(); btnclosemap.visible =false; } 方法

    所以回答你的问题(&#34;我在这里做错了什么?&#34;),我担心答案是&#34;一切都是&#34;。

答案 1 :(得分:0)

此行始终创建新实例。它没有更新任何内容。

project.save(commit=True)

您需要的是使用表单进行更新。这是提示:

 project = Project.objects.get(pk = id)
 projectform=ProjectForm(request.POST,instance=project)
    if projectform.is_valid():
       projectform.save(commit=True)
    else:
       print projectform.errors