views:

44

answers:

2

I want to populate two foreign key fields in one of my forms. The relevant bit of code is as below:

if request.method == 'POST':
    form = IssuesForm(request.POST or None)
    if request.method == 'POST' and form.is_valid():
        form.save()
else:
    form = IssuesForm(initial={'vehicle': stock_number, 'addedBy': request.user, })

vehicle points to the Vehicle class. addedBy is to contain the currently logged in user.

However the drop downs aren't initialized as I want...I still have to select the vehicle and user. From this I have two questions:

  1. What could be the problem?
  2. What is the best way to make these forms read-only?

EDIT 1 The IssueForm class looks like this so far:

class Issues(models.Model):
   vehicle = models.ForeignKey(Vehicle)
   description = models.CharField('Issue Description', max_length=30,)
   type = models.CharField(max_length=10, default='Other', choices=ISSUE_CHOICES)
   status = models.CharField(max_length=12, default='Pending', 
     choices=ISSUE_STATUS_CHOICES)
   priority = models.IntegerField(default='8', editable=False)
   addedBy = models.ForeignKey(User, related_name='added_by')
   assignedTo = models.CharField(max_length=30, default='Unassigned')
   dateTimeAdded = models.DateTimeField('Added On', default=datetime.today, 
     editable=False)
   def __unicode__(self):    
    return self.description

Form Class

class IssuesForm(ModelForm):   
  class Meta:
    model = Issues
    exclude = ('assignedTo')
A: 

For your second question, are you wanting to make the addedBy field read-only? If so, don't add it to your form (it'll never be read-only if you present it to the user, e.g. Firebug). You can instead populate it inside your save method.

if request.method == 'POST':
    form = IssuesForm(request.POST or None)
    if request.method == 'POST' and form.is_valid():
        issue = form.save(commit=False)
        issue.addedBy = request.user
        # any other read only data goes here
        issue.save()
else:
    form = IssuesForm(initial={'vehicle': stock_number}) # this is related to your first question, which I'm not sure about until seeing the form code
Adam
I was thinking that the 'vehicle': stock_number will initalize the vehicle foreign key entry
Stephen
too many checks for request.method, if you initialize the form with (request.POST or None) then everything you need to do is check for is_valid() since unbound form (in case where POST is None) doesn't have errors
Dmitry Shevchenko
@ Dmitry: I just seen the many checks...I was moving over the code from an old app I had made for the same function...thnx for the notice
Stephen
Ah, yeah, I didn't even notice the multiple method checks.
Adam
A: 

To make a form read only: on your form class, overwrite the _init_method to disable html fields:

def __init__(self, *args, **kwargs):
    super(IssuesForm, self).__init__(*args, **kwargs)
    for key in self.fields.keys():
        self.fields[key].widget.attrs = {'disabled': 'disabled'}

Makes sure you also don't listen for POST requests, if so, don't save the form. You can further customize the _init_method to take some arguments and set fields to these values after the super method has been called.

Luiz C.