Sukhrab
Sukhrab

Reputation: 95

How to connect models from different apps in Django?

I have a few apps within my Django project. There are two apps that I am currently working with "Application" and "User" and I have two questions related to models:

Question 1:

I want to design it in such a way so that external users submit their contact form on Application/templates/Application/Apply.html and the info would get added to the database. Internal users would be able to add external users as well but from a different template: User/templates/User/AddNewContact.html

I am able to add a new contact from an internal user's perspective:

User/models.py

class Contact(models.Model):
    ContactName = models.CharField(max_length = 250, default='')
    ContactResidence = models.CharField(max_length = 250, default='')
    Tel = models.CharField(max_length = 250, default='')

    def get_absolute_url(self):
        return reverse('User:ContactDetails', kwargs={'pk': self.pk}
        )

    def __str__(self):
        return self.ContactName



class Locations(models.Model):
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
    Country = models.CharField(max_length=250, default='')

    def __str__(self):
        return self.Country

I was going to just copy this model and paste it into Application/models.py but there are two problems:

1) I don't want external users to be directed to URL: User:ContactDetails and technically, it is not going to work out because I will build the authentication later on.

2) I feel that by copying and pasting I am breaking the 'don't repeat yourself" rule.

Should I connect two models using the foreign keys? What are the best practices in this case?

Question 2

Am I working with one-to-many relationship according to the model provided? I want to have one contact with his personal info (tel/email/address) and a number of branch locations across the world associated with that contact.

Upvotes: 5

Views: 12522

Answers (4)

Thịnh Nguyễn
Thịnh Nguyễn

Reputation: 111

To be used a relationship one to many, you can be doing as after:

On models of father app (father table):

class Department(models.Model):
    dept_id = models.AutoField(primary_key=True)

On models of child app (child table):

from appname.models import Department
class Office(models.Model):
    office_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)
    dept = models.ForeignKey(Department, on_delete=models.CASCADE)

It helped me.

Upvotes: 4

Parias Lunkamba Mukeba
Parias Lunkamba Mukeba

Reputation: 302

The apps should be in the same project and you can import one model as:

import appName.models or

from appName.models import ClassName

In app2 models you can use foreignKey or manyTomany after importing the class:

from appsName.models import ClassName

class Person(models.Model):
      con = ForeignKey(ClassName)

Upvotes: 0

davecaputo
davecaputo

Reputation: 341

Question 1: Note that the 'get_absolute_url' method is only called if you don't provide a success url in your view. If you are using a CreateView or FormView you can specify the success url by overriding the get_success_url method, for example:

class ContactCreateView(CreateView):
    model = Contact
    fields = ['ContactName', 'ContactResidence', 'Tel']

    def get_success_url(self):
       if not self.request.user.internal:  # e.g. internal is a User bool field 
           return HttpResponseRedirect('some/external/url/')
       return super().get_success_url()  # call get_absolute_url model method.

The DRY principle is respected.

Question 2: Yes, the question you need to ask yourself is 'does a model instance (In this case Contact) have many instances of another model (Location)?' If the answer is yes, then the M2M field should go into your Contact model. See the django docs explaining the pizza/toppings example.

Upvotes: 0

Alex
Alex

Reputation: 1262

Question 1: Well, you don't need to copy paste the model. You can use models from other django apps anytime, just need to import it. Basically what you should do is, instead of linking the url directly to the template in the Applications app, you should connect it to a view. In the view file you can import the models from User.models import *, and use them normally.

Question 2: As far as I understand the question your structure provides what you want: one contact (with personal info) associated with several countries. Except that you should replace Agent by Contact in contact = models.ForeignKey(Agent, on_delete=models.CASCADE)

Upvotes: 0

Related Questions