2👍
You can have your Project model as such
class Project(models.Model):
name = models.CharField(max_length=200)
options = models.ManyToManyField(Option, blank=True)
anyother field you wish to have
and you can continue with the Option model you have, that should suffice.
Now lets say you have options 1,2,3,4,5 and projects A and B
A may have options 1,2,3 and B may have options 2,3,4,5.
Further, you dont want to have option 1 in your project A, you simply remove it from M2M field by this statement
projectA.options.remove(option1)
So, you have deleted option1 from your project but it still persists in the database, you can add same option1 to projectB by using statement
projectB.options.add(option1)
So, now when you do
projectA.options.all()
your output will option2, option3
and projectB.options.all()
will give option1, option2, option3, option4, option5.
I hope I have explained properly, in case if its unclear leave a comment, will be happy to help.
Edit: and yes this is how it should be in your case unless you get alternative way of doing it.
Edit 2:
Post the question update, you can remove options as M2M field from Project and have a separate model by name ProjectOption. It may be like,
class ProjectOption(models.Model):
project = models.ForeignKey(Project)
option = models.ForeignKey(Option)
is_deleted = models.BooleanField(default=False)
You will still have to populate it, its a one time operation for you. So now, you will have your default options per project, if user chooses to delete one you can either set is_deleted=True or actually delete it. This will provide you with details of options that are deleted(only when you dont actually delete object but just set is_deleted=True).