I am trying to build a publication database for researchers. So my database has model classes Paper, Author and Journal. Journal is a foreign key to Paper while Author is a ManytoMany key to Paper. The model definition is thus:
from django.db import models
from django import forms
from django.forms import ModelForm, Textarea
# Create your models here.
class Journal(models.Model):
name = models.CharField(max_length = 100)
organization = models.CharField(max_length = 100, blank = True)
def __unicode__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length = 20, blank = True)
last_name = models.CharField(max_length = 20, blank = True)
middle_name = models.CharField(max_length = 20, blank = True)
full_name = models.CharField(max_length = 50)
email = models.EmailField(blank = True)
def __unicode__(self):
return self.full_name
class Paper(models.Model):
paper_title = models.CharField(max_length=200)
paper_year = models.IntegerField(blank = True, null = True)
paper_volume = models.CharField(max_length = 100, blank = True, null = True)
paper_number = models.CharField(max_length = 100, blank = True, null = True)
paper_pages = models.CharField(max_length = 100, blank = True, null = True)
paper_month = models.CharField(max_length = 15, blank = True, null = True)
paper_doi = models.CharField(max_length = 50, blank = True, null = True)
paper_abstract = models.TextField(blank = True, null = True)
paper_keywords = models.TextField(blank = True, null = True)
paper_journal = models.ForeignKey(Journal)
paper_authors = models.ManyToManyField(Author)
def __unicode__(self):
return self.paper_title
I created a database and now I am trying to use forms to let the user edit a paper. I am using ModelForm for creating the form. To edit the Author information for a paper, I am using a drop down list to let the user know a particular author in the paper may be a duplicate. The user can then check out the other author and if indeed it is a duplicate author entry, can insert the data of the other author into this paper. The block of code for this purpose is:
other_author = Author.objects.get(id = other_author_srno)
print(other_author)
replaced_author = Author.objects.get(id = author_srno)
print(replaced_author)
replaced_author_papers = replaced_author.paper_set.all()
print(replaced_author_papers)
for paper_item in replaced_author_papers:
print("initial")
print("authors")
paper_item_authors = paper_item.paper_authors.all()
print(paper_item_authors)
copy_of_paper_item_authors = []
for author in paper_item_authors:
copy_of_paper_item_authors.append(author)
print("copyofauthors")
print(copy_of_paper_item_authors)
for author in paper_item_authors:
paper_item.paper_authors.remove(author)
print("afterremove")
print(paper_item.paper_authors.all())
print(copy_of_paper_item_authors)
for author in copy_of_paper_item_authors:
if not author == replaced_author:
paper_item.paper_authors.add(author)
else:
paper_item.paper_authors.add(other_author)
paper_item.save()
print(paper_item.paper_authors.all())
print(paper_item.paper_authors.all())
So basically the replaced_author object gets replaced by the other_author object. Since, these are authors in a paper, the order of authors is important. So I made a copy of the authors (paper_authors), removed all the items for paper_authors and then add author objects from the copy except for the object that needs to be replaced. But the order of authors gets messed up. For example, say there is a paper with authors A. AAA, B. BBB, C. CCC and there is another paper with these identical authors. I want to replace them one by one since they are identical entries. But this is the output if I try to replace author B. BBB.
B. BBB
B. BBB
[<Paper: XYZ>]
initial
authors
[<Author: A. AAA>, <Author: B. BBB>, <Author: C. CCC>]
copyofauthors
[<Author: A. AAA>, <Author: B. BBB>, <Author: C. CCC>]
afterremove
[]
[<Author: A. AAA>, <Author: B. BBB>, <Author: C. CCC>]
[<Author: A. AAA>]
[<Author: A. AAA>, <Author: B. BBB>]
[<Author: A. AAA>, <Author: C. CCC>, <Author: B. BBB>]
[<Author: A. AAA>, <Author: C. CCC>, <Author: B. BBB>]
It inserts the author C. CCC in the second place. Is there some ordering aspect in ManyToMany fields that I am overlooking? I would like the ordering to be maintained.
Thanks in advance.