简体   繁体   中英

Django model with many-to-one or none relationship vs many-to-many through?

I'm trying to build a application that lets people view tweets posted by politicians, and I'm struggling with the right way to specify the relationship between a user on Twitter and a user offline. For example, one politicians may have two Twitter accounts, and those accounts may mention three other Twitter users who are not politicians. Right now, I have a User table that contains info from the Twitter API (eg, number of followers, number of tweets) that would have the Twitter info from both the politicians' accounts and those s/he mentioned and a Legislator table that contains info about legislators (eg, party, chamber).

  • Users relate to Legislators on twitter_id
  • Users can have 0 or 1 entries in the Legislator table
  • Legislators can have 0, 1, or n entries in the Users table

How would I set that model up correctly for Django? How do I access both user and legislator information in a template? With the setup below, I can't access anything in the legislator table from user.legislator_set.

class User(models.Model):
  id = models.IntegerField(primary_key=True)
  twitter_id = models.CharField(max_length=21, unique=True)
  twitter_name = models.CharField(max_length=55, unique=True)
  fullname = models.CharField(max_length=45)
  followers = models.IntegerField()
  following = models.IntegerField()
  favorites = models.IntegerField()
  tweets = models.IntegerField()
  timezone = models.CharField(max_length=45, blank=True)

class Legislator(models.Model):
  id = models.IntegerField(primary_key=True)
  last_name = models.CharField(max_length=17, blank=True)
  first_name = models.CharField(max_length=11, blank=True)
  chamber = models.CharField(max_length=3, blank=True)
  state = models.CharField(max_length=2, blank=True)
  party = models.CharField(max_length=11, blank=True)
  twitter_id = models.ForeignKey(User, to_field = "twitter_id", related_name="%(app_label)s_%(class)s_id")
  twitter = models.ForeignKey(User, to_field = "twitter_name", related_name="%(app_label)s_%(class)s_name")

Libby. If I'm understanding your requirements, this seems like the simplest starting point -- a many-to-one relationship using a ForeignKey field. (This is basically the same thing as lanzz's suggestion.)

class User(models.Model):
  twitter_id = models.CharField(max_length=21, unique=True)
  twitter_name = models.CharField(max_length=55, unique=True)
  # ... other fields characterizing a Twitter account
  legislator = models.ForeignKey('Legislator', blank=True, null=True)

class Legislator(models.Model):
  last_name = models.CharField(max_length=17, blank=True)
  first_name = models.CharField(max_length=11, blank=True)
  # ... other fields characterizing a legislator

In your Python code, given a twitter account u and legislator l , you'd run u.legislator = l to associate a legislator with a twitter account. You could also express that as l.user_set.add(u) , which makes more sense to me given these models.

Similarly, you'd use Legislator.user_set to access the RelatedManager for twitter accounts. This is what you'd loop over in a template or do additional queries against when you want to work with the related model (any/all related twitter accounts) instead of the one you have (a legislator).

There are a few more usage examples in the docs .

In the ForeignKey field, I set blank=True, null=True to make the relationship optional. Unless you specify otherwise in the field's options, Django will create and use a legislator_id column in the User table to manage the relationship.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM