form is_valid() failing due to Foreign Key

1k Views Asked by At

I don't understand why my form isn't valid right now. Every time I submit my form, if it's invalid I simply have the website reload. I thought that I was submitting it correctly and I've tried several different things to get this working but I'm at wits end right now. I'm pretty sure the error is in the Error key that I'm using to reference my User object (I want to register a device and register it to a logged in user)

views.py:

def devices(request):
    if request.method == 'POST':
        devform = DeviceForm(request.POST, owner=request.user)
        if devform.is_valid():
            dev = devform.save()
            dev.save()
            return HttpResponseRedirect(reverse('deviceconfirmation', kwargs={'device_id': dev.id}))
        else:
            return render_to_response('courses/devices.html', {'devform': devform}, context_instance=RequestContext(request))
    else:
        devform = DeviceForm()
    return render_to_response('courses/devices.html', {'devform': devform}, context_instance=RequestContext(request))

models.py:

class DeviceForm(ModelForm):

  class Meta:
        model = Device
        fields = ['name', 'agent_id', 'device_type', 'owner']

    def __init__(self, *args, **kwargs):
        self.owner = kwargs.pop('owner', None)
        super(DeviceForm, self).__init__(*args, **kwargs)

    """def clean_agent_id(self):
        agent_id = self.cleaned_data['agent_id']
        if Device.objects.exclude(pk=self.instance.pk).filter(agent_id=agent_id).exists():
            raise forms.ValidationError(u'agent_id "%s" is already in use.' % agent_id)
        return agent_id
        """

    def save(self, commit=True):
        device = super(DeviceForm, self).save(commit=False)
        device.owner = self.owner
        if commit:
            device.save()
        return device

sidenote: I have the clean_agent_id method commented out because when I try and use it to prevent duplication of devices I get a "this query not supported by the database error" I'm using MongoDB as my database so I don't need to make any migrations or anything like that.

1

There are 1 best solutions below

0
user3393571 On

I think I figured out why it wasn't passing. Simply referencing the username was not enough so what I had to do was manually add in the username (I looked on the ModelForm page of the Django Forms website for how to do this). What I had to do was 1. Remove the Owner field from my form in the template. 2. 'exclude' the owner field from my models.py for the DeviceForm model and 3. Manually set the Owner using the current logged in user on the views.py.

devices.html:

{% extends "layout.html" %}
{% load static from staticfiles %}

{% block title %}{{ page.title }}{% endblock %}
{% block content %}
<article>
    <div id="wrapper">
        <p id="devicecreate">Register your device to your account:</p>
        <form action="{% url 'courses:devices' %}" id="devform" method="post"> {% csrf_token %}
            <p>
                <label for="name">Device Name:</label>
                <input id="name" name="name" type="text">
            </p>
            <p>
                <label for="agent_id">Agent ID:</label>
                <input id="agent_id" name="agent_id" type="text">
            </p>
            <p>
                <label for="device_type">Imp Type:</label>
                <input id="device_type" name="device_type" type="text">
            </p>
            <p>
                <input type="submit" value="REGISTER DEVICE" id="submit">
            </p>
        </form>
    </div>
</article>
{% endblock %}

models.py:

class DeviceForm(ModelForm):
    class Meta:
        model = Device
        exclude = ['owner']

    def __init__(self, *args, **kwargs):
        self.owner = kwargs.pop('owner', None)
        super(DeviceForm, self).__init__(*args, **kwargs)

views.py:

def devices(request):
    dev_obj = DeviceForm()
    if request.method == 'POST':
        u = User.objects.get(username=request.META['USER'])
        devowner = Device(owner=u)
        devform = DeviceForm(request.POST, instance=devowner)
        if devform.is_valid():
            dev = devform.save()
            dev.save()
            return HttpResponseRedirect('deviceconfirmation')
        else:
            return render(request, 'courses/invalidimp.html', {'devform':devform})
    else:
        return render_to_response('courses/devices.html', {'dev_obj': dev_obj}, context_instance=RequestContext(request))

this gets me past just the is_valid() and gets the owner model correctly. I'm still having issues with saving the form but I think this adequately answers the question of why my is_valid() wasn't passing.