Reputation: 405
I am designing a model, view and template for my news aggregation app. I want the template to offer the user a multiple-choice field form with options from the database. How do I design this in my model?
I was reading the Django documentation about ManyToManyField (the one with journalists and articles) but I don't think that is quite the right relationship because in my case, "articles" can exist without a journalist and journalist without an article.
I have Users. I have Streams. Streams is a collection of news sites a user can sign up to follow and see aggregated headline snippets, such as from CNN,Twitter, Google News, etc etc. A Stream can exist with no Users. A Stream can have many Users. A User can have no Streams, in fact all user accounts start in my app with no Streams until they choose one. A User can have many Streams.
In the template, I want to create a form with the list of all the Stream options in the database (this will likely change as I ad more options in the future). When a User selects a Stream, it will be added to their dashboard view. They can add and delete Streams. However, there is only 1 Twitter, 1 Google News, etc source. I can't use the typical choices option in the User model, I want it to be "dynamic" and pull straight from the Streams database.
This is what I have now but I know it's not right:
streams/models.py
from django.db import models
from django.contrib.auth.models import User
class Stream(models.Model):
user = models.ManyToManyField(User, blank=True, null=True)
name = models.CharField(max_length=30)
user/models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=30)
'''''
#TODO: make this dynamic, streams is pulling from Streams model
streams = (
('Google News'),
('Yahoo News'),
('Twitter'),
('CNN'),
('New York Times'),
('NBC News'),
('Huffington Post')
)
stream_choices = models.CharField(max_length=9, choices=streams)
'''''
Upvotes: 1
Views: 3297
Reputation: 101
The ManyToManyField
already implicitly creates the 'intermediary table' described in the accepted answer. As per the documentation:
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship.
You can pass a callable to the choices
field of the ChoicesField
which you display to the user, allowing the list of available choices to be determined dynamically when the form is generated.
The list of valid choices in the User<->Stream relationship is already constrained by the relationship, so there's no benefit in specifying the available choices on the model field.
Upvotes: 0
Reputation: 3364
Just add one model for list of streams and another model for user selected streams
class Stream(models.Model):
name = models.CharField(max_length=50)
class UserStream(models.Model):
user = models.ForeignKey(User)
name = models.ForeignKey(Stream)
That's it. Insert possible streams to Stream
model and user selected streams to UserStream
model.
Upvotes: 1