Manually listing objects in Django (problem with field ordering)
I'm having some trouble figuring out the best/Djangoic way to do this. I'm creating something like an interactive textbook. It has modules, which are more or less like chapters. Each module page needs to list the topics in that module, grouped into sections.
My question is how I can ensure that they list in the correct order in the template? Specifically:
1) How to ensure the sections appear in the correct order?
2) How to ensure the topics appear in the correct order in the section?I imagine I could add a field to each model purely for the sake of ordering, but the problem with that is that a topic might appear in different modules, and in whatever section they are in there they would again have to be ordered somehow.
I would probably give up an开发者_StackOverflow中文版d do it all manually were it not for the fact that I need to have the Topic as object in the template (or view) so I can mark it up according to how the user has labeled it.
So I suppose my question is really to do with whether I should create the contents pages manually, or whether there is a way of ordering the query results in a way I haven't thought of. Thanks for your help!
edit: The simplest thing I can think of would be if I could have an ordered list (of topics) in the module or section model, but afaik that's not possible. Is it? Perhaps with a custom field?
So your structure is basically module/section/topic, and topics can appear in more than one section.
Basically, you want this (content fields omitted):
class Module(models.Model):
title = CharField(max_length=100)
class Section(models.Model):
topics = ManyToManyField(Topic, related_name="sections",
through='TopicEntry')
module = models.ForeignKey(Module, related_name="sections")
class Topic(models.Model):
text = models.TextField()
class TopicEntry(models.Model):
section = models.ForeignKey(Section)
topic = models.ForeignKey(Topic)
order = models.IntegerField()
See Extra Fields on Many-to-Many Relationships for more information on ManyToManyField.through
. The docs aren't perfectly clear, though. If I read them right, to get your table of contents, use something like:
topicList = Topic.objects.filter(section=section).order_by("TopicEntry__order")
# Might be "topicEntry__order" or "topicentry__order" instead; the docs aren't
# clear how it transforms the name of the intermediate model.
# This also works:
topicList = section.topics.all().order_by("TopicEntry__order")
I would use a table in your database specifically for ordering topics in modules eg:
Topic | Module | Order
A | mod1 | 2
B | mod1 | 1
C | mod1 | 3
C | mod2 | 2
A | mod2 | 3
B | mod2 | 1
It may not be the best method but it's how I've solved the issue in my own app.
To order the data you simply use .order_by("field_name") on the end of your model.objects.filter() statement.
精彩评论