Many-to-many relationship children exclusive to parent model. How?

79 views Asked by At

If there is a way to better word the title of this question please let me know.

In django I am attempting to create this sort of hierarchy of models:

User
-Author [Author model]
--Sentence [Sentence model]
--Find_Replace [FindReplace model]

A user sets up multiple authors as "pen names". An author has his own sentences, and his own predefined find/replace sets. A sentence can be associated with multiple find/replace sets, but only with the sentences created by that author.

The thing I am getting stumped on is this: How do you make such a relationship?

Here is what I have - without programmatic amendments, I am at a loss as to a good way to keep these relationships strictly defined.

Here are the models thus far, only partially correct:

class Author(models.Model):
    created_by = models.ForeignKey(User)  


class FindReplace(models.Model):     
    created_by = models.ForeignKey(User)   
    author = models.ForeignKey(Author)              

    find = models.CharField(max_length=256)
    replace = models.CharField(max_length=5000)


class Sentence(models.Model):      
    created_by = models.ForeignKey(User)   
    account = models.ForeignKey(Account)   


    text = models.CharField(
        max_length=500, 
        blank=False, 
        null=False, 
        )
3

There are 3 answers

0
ruddra On BEST ANSWER

I don't see why you will require created_by field in every model, because they are related to Author hence related to User. I will suggest to use like this:

class Author(models.Model):
    created_by = models.ForeignKey(User)  


class FindReplace(models.Model):       
    author = models.ForeignKey(Author)              

    find = models.CharField(max_length=256)
    replace = models.CharField(max_length=5000)


class Sentence(models.Model):        
    account = models.ForeignKey(Account)  #Is account related to user? The you can query it by user.
    # Or add an FK relation to Author. 


    text = models.CharField(
        max_length=500, 
        blank=False, 
        null=False, 
        )

About strictly maintaining the rule, you can't define that in model structure. You can use model validation or Modelform validation or write your own function in models like this: (For Example)

class FindReplace(models.Model):       
        author = models.ForeignKey(Author)              

        find = models.CharField(max_length=256)
        replace = models.CharField(max_length=5000)

       def _validate_creation(self, user_id):
          if self.author.created_by.id == user_id:
              return True
          else:
              return False

Usage: in views.py:

def someview(request):
      fr= FindRepace()
      fr.author = author_obj
      fr.find = 'Foo'
      fr.replace = 'Bar'

      if fr._validate_creation(request.user.id):
         fr.save()
0
Ben Hsieh On

Why do you need Author model? Author = User, django will auto create a relation for you

0
Sidy Funda On

Here is the model where we use foreign key:

class Department(models.Model):
dept_id = models.CharField(primary_key=True,max_length=20,unique=True)
dept_name = models.CharField(max_length=20)
dept_add = models.CharField(max_length=30)

def _str_(self):
     return "%s,%s" % (self.dept_id, self.dept_name)

class Emp_Department(models.Model):
    emp_no = models.ForeignKey(Employee)
    dept_id = models.ForeignKey(Department)
    emp_type = models.CharField(max_length=30)
    desi_id =  models.CharField(max_length=30)
    join_date = models.DateField()
    retire_date = models.DateField()