Alex
Alex

Reputation: 4345

Django ForeignKey Relationship Constraint

Can I enforce a ForeignKey relationship such that an Article written by a Reporter cannot be written by another Reporter?

I'm trying to implement "object containment" and support assignment of Articles to Reporter "folders".

For example, a ReporterOne "folder" contains Articles A,B,C and if Articles A,B,C are "assigned to" (i.e. contained within) ReporterOne's folder, they cannot be assigned to ReporterTwo.

Upvotes: 1

Views: 416

Answers (2)

jsmedmar
jsmedmar

Reputation: 1125

Article has ForeignKey to Reporter. As such each Article will only belong to one Reporter. Then add an attribute called folder to Article and use it as a hash key to determine what Articles are "contained" in a folder.

To find all the Articles that are in a folder called Foo for a given Reporter you could do a query like this:

reporter = Reporter.objects.first()
articles_in_folder = reporter.articles_set.filter(folder='Foo')

Note that folder could also be an entire model and not just a string. An Article would have a ForeingKey to folder and folder could also have a ForeingKey to Reporter.

Upvotes: 0

jsmedmar
jsmedmar

Reputation: 1125

Use OneToOneField. From the docs:

To define a one-to-one relationship, use OneToOneField. In this example a Place optionally can be a Restaurant:

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

    def __str__(self):              # __unicode__ on Python 2
        return "%s the place" % self.name

class Restaurant(models.Model):
    place = models.OneToOneField(Place, primary_key=True)
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

    def __str__(self):              # __unicode__ on Python 2
        return "%s the restaurant" % self.place.name

class Waiter(models.Model):
    restaurant = models.ForeignKey(Restaurant)
    name = models.CharField(max_length=50)

    def __str__(self):              # __unicode__ on Python 2
        return "%s the waiter at %s" % (self.name, self.restaurant)

Upvotes: 1

Related Questions