Django form.save () очищает данные объекта модели - PullRequest
0 голосов
/ 14 мая 2011

У меня есть модель Django с кучей полей, которые описывают рабочий заказ.Затем у меня есть форма, созданная с помощью ModelForm, но только с использованием нескольких полей модели.Вот моя форма:

class Service_Call_Form(ModelForm):
class Meta:
    model = Work_Order
    fields = ('dateWOCreated', 'dateWORequired', 'problemDescription',
    'resolutionDescription', 'notesToCrew', 'numHours', 'numWorkers')

У меня есть HTML шаблон создания задания , который показывает все поля, но НЕ «resolutionDescription».Напротив, существует шаблон HTML Work Order Completed , который показывает only поле «resolutionDescription» (поскольку все, что нужно сделать пользователю, это объяснить, как проблема была решена, а неотредактируйте оригинальную проблему).

Что я не понимаю, так это то, что когда я нажимаю кнопку «Сохранить» в форме шаблона, чтобы завершить рабочий заказ, все поля, которые отображаются для Создать рабочий заказ шаблон очищается до пустого, и поле для решения проблемы остается.Кроме того, все поля модели, которые я установил в представлении (и, следовательно, не редактируются пользователем), остаются в курсе.

Почему это происходит?

Мои просмотры:

def create_service_call(request):
if request.method == 'POST':
    form = Service_Call_Form(request.POST)
    if form.is_valid():
        wo = form.save(commit=False)
        if wo.woID == None:
            wo.woID = new_wo_id()
        wo.dateWOCreated = datetime.date.today()
        wo.systemID = System.objects.get(systemID='2')
        wo.woType = 'R'
        wo.isComplete = 'N'
        wo.save()
        return HttpResponseRedirect('/work-orders/')
else:
        form = Service_Call_Form()
return render_to_response("pages/work_orders/create_service_call.html", {'form': form}, context_instance=RequestContext(request))


def complete_service_call(request, scwoID):
if request.method == 'POST':
    woEdit = Work_Order.objects.get(pk=scwoID)
    form = Service_Call_Form(request.POST, instance = woEdit)
    if form.is_valid():
        form.save()
        return HttpResponseRedirect('/work-orders/')
else:
    if scwoID == None:
        #Really, this should never happen (not have a woID in the url)
        return HttpResponseRedirect('/work-orders/', context_instance=RequestContext(request))
    else:
        wo = Work_Order.objects.get(pk=scwoID)
        form = Service_Call_Form(instance=wo)
return render_to_response("pages/work_orders/complete_service_call.html", {'form': form}, context_instance=RequestContext(request))

Модель:

class Work_Order(models.Model):
IS_COMPLETE_CHOICES = (
    ('Y', 'Yes'),
    ('N', 'No'),
)

WO_TYPE_CHOICES = (
    ('P', 'Plumb'),
    ('I', 'Install'),
    ('S', 'Show'),
    ('R', 'Service'),
    ('B', 'Blow down'),
    ('U', 'Start up'),
)

woID = models.CharField(max_length = 10, primary_key = True, default = new_wo_id(), verbose_name = 'Work Order ID')
woType = models.CharField(max_length = 2, verbose_name = 'WO Type', default='R', choices = WO_TYPE_CHOICES)
systemID = models.ForeignKey(System, verbose_name = 'System ID')
notesToCrew = models.TextField(blank = True, null = True, verbose_name = 'Notes to Crew')
dateWOCreated = models.DateField(blank = True, null = True, default=datetime.date.today(), verbose_name = 'Date Created')
dateWORequired = models.DateField(blank = True, null = True, verbose_name = 'Date Required')
numDays = models.DecimalField(max_digits = 3, decimal_places = 0, verbose_name = 'Number of Days to Complete', blank = True, null = True)
numHours = models.DecimalField(max_digits = 3, decimal_places = 2, verbose_name = 'Number of Hours to Complete', blank = True, null = True)
isComplete = models.CharField (max_length = 3, default = 'N', verbose_name = 'Is WO Complete?', choices = IS_COMPLETE_CHOICES)
problemDescription = models.TextField(verbose_name = 'Problem Description', blank = True, null = True)
resolutionDescription = models.TextField(verbose_name = 'Resolution Description', blank = True, null = True)
numWorkers = models.DecimalField(max_digits = 3, decimal_places = 0, verbose_name = 'Number of Workers Required', blank = True, null = True)

def __unicode__(self):
    return u'%s - %s' % (self.woID, self.systemID.systemAddress)

class Meta:
    ordering = ['woID']

1 Ответ

2 голосов
/ 14 мая 2011

У вас должно быть две формы, поскольку у вас есть два совершенно разных типа вводимых данных. Первым может быть ModelForm (так как он сохраняет несколько полей в Model):

class Service_Call_Form(ModelForm):
    class Meta:
        model = Work_Order
        fields = ('dateWOCreated', 'dateWORequired', 'problemDescription',
                  'notesToCrew', 'numHours', 'numWorkers')

и один, содержащий только ResolutionDescription, который я бы оставил как обычную форму (поскольку он обновляет только одно поле в модели). Вы также можете захотеть, чтобы идентификатор модели был скрытым полем, если оно отсутствует в URL-адресе или добавлено в запрос. В противном случае используйте POST.

class Resolution_Description_Form(forms.Form):
     resolution_description = forms.TextField(max_length=100)

Если шаблон был из Service_Call_Form, ваше представление сохранено правильно; если у вас есть что-то с resolution_description, вам просто нужно обновить это поле в функции, например:

def complete_work_order(request, scwoID):
    if request.method == 'POST':
        woEdit = Work_Order.objects.get(pk=scwoID)
        form = Resolution_Description_Form(request.POST)
        if form.is_valid():
            woEdit.resolution_description = form.cleaned_data.get('resolution_description')
            woEdit.save()
            return HttpResponseRedirect('/work-orders/')
     ...

РЕДАКТИРОВАТЬ: вы также можете просто иметь только две ModelForm, если хотите. Например,

class Resolution_Description_Form(ModelForm):
    class Meta:
        model = Work_Order
        fields = ('resolutionDescription', )

и просто используйте соответствующую ModelForm в соответствующем шаблоне и сохраните, как вы сохраняли ранее.

...