Reputation: 95
class Publisher(models.Model):
name = models.CharField(max_length=300, null=True, blank=True)
class Book(models.Model):
name = models.CharField(max_length=300, null=True, blank=True)
publisher = models.ManyToManyField(Publisher,related_name='b', null=True)
_published_at = models.DateTimeField()
from polls.models import Book, Publisher
p1=Publisher.objects.get(id=1)
p1.b.clear()
p1.save()
b6=Book.objects.get(id=6)
p1.b.add(b6)
b6._published_at = datetime.now()
p1.save()
b5=Book.objects.get(id=5)
p1.b.add(b5)
b5._published_at = datetime.now()
p1.save()
b7=Book.objects.get(id=7)
p1.b.add(b7)
b7._published_at = datetime.now()
p1.save()
p2 = Publisher.objects.get(id=2)
p2.b.clear()
p2.save()
b7=Book.objects.get(id=7)
p2.b.add(b7)
b7._published_at = datetime.now()
p2.save()
b6=Book.objects.get(id=6)
p2.b.add(b6)
b6._published_at = datetime.now()
p2.save()
b5=Book.objects.get(id=5)
p2.b.add(b5)
b5._published_at = datetime.now()
p2.save()
print p1.b.order_by("_published_at")
print p2.b.order_by("_published_at")
It prints
[Book: b7, Book: b6, Book: b5]
[Book: b7, Book: b6, Book: b5]
While I want it to print in the same order as I added them like this
[Book: b6, Book: b5, Book: b7]
[Book: b7, Book: b6, Book: b5]
Upvotes: 2
Views: 119
Reputation: 7193
When you add them you lose track of the order in which you add them because it only sets the foreign key of the Book.
What you can do is add a DateTimeField
() to your Book and set it when you add it to a publisher and order_by it.
something like:
class Book(models.Model):
name = models.CharField(max_length=300, null=True, blank=True)
_published_at = models.DateTimeField()
publisher = models.ForeignKey(Publisher,related_name='b', null=True)
the when you add it
p=Publisher.objects.get(id=2)
p.b.clear()
p.save()
b6=Book.objects.get(id=6)
p.b.add(b6)
b6._published = datetime.now()
b6.save()
p.save()
b5=Book.objects.get(id=5)
p.b.add(b5)
b5._published = datetime.now()
b5.save()
p.save()
b7=Book.objects.get(id=7)
p.b.add(b7)
b7._published = datetime.now()
b7.save()
p.save()
and when you prints it:
p.b.order_by("_published_at")
EDIT:
for your question about the ManyToManyField
you need a custom "through" model
see https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships
class Publisher(models.Model):
name = models.CharField(max_length=300, null=True, blank=True)
class Book(models.Model):
name = models.CharField(max_length=300, null=True, blank=True)
publisher = models.ManyToManyField(Publisher,related_name='b',through="Publication",null=True)
_published_at = models.DateTimeField()
class Publication(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
_published_at = models.DateField()
class Meta:
ordering = ['_published_at']
Also you cannot use add()
to add new publisher you need to define the new models to do so.
so to add Publisher p3 to book b7 you need to do
Publication.objects.create(book=b7, publisher=p3, _published_at=datetime.now())
they should be ordered automatically by now
Upvotes: 3