Django - when user submits a form, tables are created, but the connection between the tables is not

Viewed 43

i am working on a small project where a customer can go to my website and register phone numbers associated to their name. it is a connection-wise registration (where number1 <--> number2 is one connection), so only two phone numbers are ever registered per session. when viewing a particular phone number (in admins panel, for instance), i want to see the id of the user it belongs to and the id of the connection it is part of. When i view a connection the same way, i want to see who registered that particular connection, and the two phone numbers that were registered in the same session.

my problem: all of the foreign keys give a "django.db.utils.IntegrityError: NOT NULL constraint failed" error. I had to set null=True for all of the foreign keys for the customer's data to be submitted at all. the ManyToManyField doesn't give any bugs - but it doesn't limit each Connection to only the two phone numbers registered in the session like it should.

and so, this kind of structured connection outlined above isn't made when the data is added. it's like each phone number and each connection and each user becomes its own little island, without ties to the other tables. when i click into 'connections' in the admin panel, each connection that's been made is listed there, but when i select it, i see all the phone numbers ever registered. it's the same for every single connection i choose. and when i select a phone number, there's nothing that connects it to the user who added it, or the 'connection that it's part of.

my models.py file:

from django.db import models 

class Customer(models.Model):
    customer_name = models.CharField(max_length=100)
    customer_email = models.CharField(max_length=100)

class Phonenumber(models.Model):
    customer_number = models.CharField(max_length=100)
    belongs_to = models.ForeignKey(Customer, on_delete=DO_NOTHING)

class Connections(models.Model):
    registered_at = DateTimeField(auto_now=True)
    got_number_at = DateTimeField(default=None)  # this becomes the date the connection was made
    registered_by = models.ForeignKey(Customer, on_delete=DO_NOTHING)
    phonenumber_id = models.ManyToManyField(Phonenumber)

my phonebook_form.py file:

from django.forms import ModelForm
from django import forms
from .models import *

class CustomerForm(ModelForm):
    class Meta:
        model = Customer
        fields = ['name', 'email']

        widgets = {
            'name': TextInput(attrs={'class':'form-control', 'id': 'cus_name'})}
            'email': TextInput(attrs={'class':'form-control', 'id': 'cus_email'})}

class NumberForm(ModelForm):
    class Meta:
        model = Phonenumber
        fields = ['customer_number']

        widgets = {
            'customer_number': TextInput(attrs={'class':'form-control', 'id': 'cus_number'})}

class ConnectionForm(ModelForm):
    class Meta:
        model = Connections
        fields = ['got_number_at']

        widgets = {
            'got_number_at': TextInput(attrs={'class':'form-control', 'id': 'connection_date'})}

my views.py file:

from django.shortcuts import render
from .phonebook_form import *

from1 = CustomerForm()
form2 = NumberForm()
form3 = ConnectionForm()

if request.method = "POST":
    form_customer = CustomerForm(request.POST)
    form_number = NumberForm(request.POST)
    form_connection = ConnectionForm(request.POST)
    if form_customer.is_valid():
        form_customer.save()
    if form_number.is_valid():
        form_number_save()
    if form_connection.is_valid():
        form_connection.save()

context = {'form1': form1,
           'form2': form2,
           'form3': form3
           } 

return render(request, 'phoneBook/phonebook.html') 

i've also added a picture of the relational schema of the database:

i don't even know where to start to fix this issue. i've watched so many django website builder tutorials and read so many articles, and all of them seem to do it exactly the same way without any issues. What am i missing? (though i've been using python for 2 years now, i'm a complete beginner in Django (1 week) and web development in general, so the simpler the fix the better)

1 Answers

Your forms will check if the phone number is correct (the fields of your form), and if that is the case save a record in the database, but it will not link to items that happen to be saved in the same view. It is not said that you want to link these object in any way, or perhaps there are a lot of ways to connect this. Forms will thus not look what another form constructed. The programmer will have to implement the linking logic.

We can first check if all forms are valid, and then use the object wrapped in one form to set it to the object wrapped in another form, like:

if form_customer.is_valid() and form_number.is_valid() and form_connection.is_valid():
    customer = form_customer.save()
    form_number.instance.belongs_to = customer
    phone_number = form_number_save()
    form_connection.instance.registered_by = customer
    connecion = form_connection.save()
    connection.phonenumber_id.add(phone_number)

Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.

Related