2016-01-17 43 views
1

我爲我的應用程序設置頁面創建了一個ModelForm(Django 1.9.1)。它應該以下面的方式工作:ModelForm的問題

  1. 設置頁面應該有多個文本字段與數據庫中的值。
  2. 如果我改變任何字段,然後按下「保存」按鈕 - 它應該更新數據庫中的相同字段,而不是添加新的。

型號:

class Settings(models.Model): 
    pkey_path = models.CharField(max_length=255) 

    class Meta: 
     db_table = "t_settings" 

    def __str__(self): 
     return self.id 

形式:

class SettingsForm(ModelForm): 
    class Meta: 
     model = Settings 
     fields = ['pkey_path'] 

查看:

def settings_update(request): 
    if request.method == "POST": 
     form = SettingsForm(request.POST) 
     if form.is_valid(): 
      form.save() 
      return render(request, 't_settings/index.html', {'form': form}) 
    else: 
     form = SettingsForm() 
    return render(request, 't_settings/index.html', {'form': form}) 

urls.py:

app_name = 't_settings' 
urlpatterns = [ 
    url(r'^$', views.index, name='index'), 
    url(r'^update/', views.settings_update, name='settings-update'), 
] 

HTML表單:

<form action="{% url 't_settings:settings-update' %}" method="post" class="form-horizontal"> 
      {% csrf_token %} 
      <div class="box-body"> 
      <div class="form-group"> 
       <label for="{{ form.pkey_path.id_for_label }}" class="col-sm-3 control-label">test</label> 
       <div class="col-sm-8">{{ form.pkey_path.errors }} 
       <input type="text" class="form-control" 
         name="{{ form.pkey_path.name }}" 
         id="{{ form.pkey_path.id_for_label }}" 
         placeholder="Path" 
         value="{{ form.pkey_path.value }}"> 

我嘗試使用Django文檔不同的方法,但無論如何,我得到:

  1. {{ form.pkey_path.value }}不顯示在從模板數據庫中的值
  2. 形式本身的工作原理,但在數據庫中添加新行,而不是更新現有的行
+0

嘗試閱讀本文,看看是否有幫助:http://stackoverflow.com/questions/10205657/django-modelform-create-or-update –

回答

0

您可以將模型的保存方法覆蓋爲c heck如果pkey_path已經存在並覆蓋現有的記錄,如果是的話。

from django.core.exceptions import ObjectDoesNotExist 

class Settings(models.Model): 
    pkey_path = models.CharField(max_length=255) 

    class Meta: 
     db_table = "t_settings" 

    def __str__(self): 
     return self.id 

    def save(self, *args, **kwargs): 
     try: 
      # will update existing record 
      self.pk = Settings.objects.get(pkey_path=self.pkey_path).pk 
     except ObjectDoesNotExist: 
      # if not existing record, will write a new one 
      self.pk = None 
     # call the original save method 
     super(Settings, self).save(*args,**kwargs) 

注意,只會有關聯的W /如果成功保存爲您的視圖列表現在形式的實例。

如果這種觀點僅僅是更新現有記錄,你可以做以下的所以總有一個實例:

查看:

from django.shortcuts import get_object_or_404 
from my_app.models import Settings 
def settings_update(request, pkey_path=None): 
    instance = get_object_or_404(Settings,pkey_path=pkey_path) 

    if request.method == "POST": 
     form = SettingsForm(request.POST, instance=instance) 
     if form.is_valid(): 
      form.save() 
      return render(request, 't_settings/index.html', {'form': form}) 
    else: 
     form = SettingsForm(instance=instance) 
    return render(request, 't_settings/index.html', {'form': form}) 

您必須添加一個條目,urls.py包括(?P<pkey_path>.+)爲這個視圖,以便它獲取現有的設置記錄。要添加新記錄,您可以編寫settings_add視圖,或者如果沒有提供給視圖的pkey_path使instance=Settings()實例化設置模型的空實例。

編輯#2:處理新記錄vs現有記錄需要的不僅僅是您的視圖。這是一種方法。

在urls.py:

urlpatterns = patterns('', 
    url(r'^settings/$',views.settings_update, name='add-settings'), 
    url(r'^settings/(?P<pkey_path>.+)/$',views.settings_update, name='update-settings'), 
    # ... 
) 

在意見。潘岳:

from django.shortcuts import get_object_or_404 
from my_app.models import Settings 


def settings_update(request, pkey_path=None): 
    if pkey_path: # if supplied via url, find record w/ pkey_path. If pkey_path supplied matches no records, return 404. 
     instance = get_object_or_404(Settings,pkey_path=pkey_path) 
    else: # if pkey_path not supplied in url, create empty instance 
     instance = Settings() # instantiate new Settings object 

    if request.method == "POST": # if post submitted, save if valid 
     form = SettingsForm(request.POST, instance=instance) 
     if form.is_valid(): 
      form.save() 
      return render(request, 't_settings/index.html', {'form': form}) 
    else: # no post submitted 
     form = SettingsForm(instance=instance) 
    return render(request, 't_settings/index.html', {'form': form}) 
+0

設置頁面應該打開「/ settings/URL。我怎樣才能得到頁面加載過程中? – DzLL

+0

請不要刪除以前的評論,他們可能會幫助未來的讀者 –

+0

所以,你想要一個單一的視圖,有人在你的表單中輸入pkey_path,並創建一個新的記錄,如果不存在或覆蓋現有的記錄如果用戶輸入一個現有的pkey_path?不用粗魯,但在Modelforms和Django UrlConf上做更多的教程可能是好的,但有一些基本的做法可能會顯示你的問題 –

0

你沒有做任何事情在你看來要麼讓現有的設置條目傳遞到形式,或告知形式之一,在保存更新。你需要有一些方法來識別你想要的對象,一開始,這通常意味着接受URL中的id或slug;那麼您需要查詢該對象並將其傳遞給參數instance,並且在初始實例化和保存之前。

+0

但是如果我有多個字段?我應該把他們全部到URL? – DzLL

+0

正如伊恩建議的那樣,使用formset。 –