views:

18

answers:

1

Hello everyone.

I have a small question to ask the community. I am wondering why my foreign key will not show up when I go to my edit form. When I go to edit the information, all my data is populated except for status (which is a foreignkey that points from the status table to project table), which is left with nothing selected. I use the same forms.py for both adding and editing information.

models.py

from django.db import models
from clients.models import Clients
from django.contrib.auth.models import User
from settings import STATUS_CHOICES

class Project(models.Model):
 client = models.ForeignKey(Clients, related_name='projects')
 created_by = models.ForeignKey(User, related_name='created_by')


 #general information
 proj_name = models.CharField(max_length=255, verbose_name='Project Name')
 pre_quote = models.CharField(max_length=3,default='10-')
 quote = models.IntegerField(max_length=10, verbose_name='Quote #', unique=True)
 desc = models.TextField(verbose_name='Description')
 starts_on = models.DateField(verbose_name='Start Date')
 completed_on = models.DateField(verbose_name='Finished On')

 def __unicode__(self):
    return u'%s' % (self.proj_name) 

 def current_status(self):
        try:
                return self.status.all().order_by('-id')[:1][0]
        except:
            return None



class Status(models.Model):
 project = models.ForeignKey(Project, related_name='status')
 value = models.CharField(max_length=20, choices=STATUS_CHOICES, verbose_name='Status')
 date_created= models.DateTimeField(auto_now=True) 

 def __unicode__(self):
    return self.value

 class Meta:
    verbose_name = ('Status')
    verbose_name_plural = ("Status")

views.py

@login_required
def addProject(request):
if request.method == 'POST':
    form = AddSingleProjectForm(request.POST)
    if form.is_valid():
        project = form.save(commit=False)
        project.created_by = request.user  
        project.save()
        project.status.create(
                value = form.cleaned_data.get('status', None)
        )            
        return HttpResponseRedirect('/project/')
else:
    form = AddSingleProjectForm()

return render_to_response('project/addProject.html', {
'form': form, 'user':request.user}, context_instance=RequestContext(request))

@login_required
def editProject(request, proj_id):
 proj = Project.objects.get(pk=proj_id) 
 if request.method == 'POST':
    form = AddSingleProjectForm(request.POST,instance=proj)  
    if form.is_valid():    
        form.save()
        return HttpResponseRedirect('/project/')
else:
    form = AddSingleProjectForm(instance=proj)

return render_to_response('project/edit_project.html', {
        'form': form}, context_instance=RequestContext(request))

forms.py

from django.db import models
from project.models import Project, Status
from django.forms import *
from django import forms
from settings import STATUS_CHOICES

class AddSingleProjectForm(ModelForm):
  status = forms.ChoiceField(choices=STATUS_CHOICES)
  class Meta:
        model = Project
        exclude = ('pre_quote', 'created_by')

Snippet from editproject template:

{% block content %}
<FORM METHOD="POST" ACTION="">
{% csrf_token %}
<table>
  {{ form.as_table }}
</table>
<input type="submit" value="Save Project">
</FORM>
{% endblock %}

Any suggestions would be greatly appreciated.

Thank you.

A: 

I think this is because project is defined as a ForeignKey on status, and not the other way around. ForeignKey is a One-To-Many relationship. Each project can have multiple statuses connected to it.

That's why on the project instance you'll find: project.status_set and not project.status.

You'll need to add the status to the form manually, by looking for the latest status connected to the project. Or perhaps change the ForeignKey to a OneToOne relationship, depending on your requirements.

OmerGertel
Ok if I was to add it to the form manually, where would I go to start that? Sorry I am still new to this. Thanks for the quick response!
Steve
Try overriding the form `__init__`. If the `__init__` gets `instance`, you find the status (`s = Status.objects.filter(project=instance).order_by('-date_created')[0]`) and add the initial value to `self.status.initial = s.value`. I hope this works (not sure).
OmerGertel
I added:def __init__(self, *args, **kwargs): super(AddSingleProjectForm, self).__init__(*args, **kwargs) self.fields['status'].initial = self.instance.current_status()to my forms.py and that allowed me to pull it onto the editform. Thanks for your help!
Steve