Django : Multiple class choices for OneToOneField - django

I would like to find a solution to be able to set "multiple choices" in OneToOneField relation. I want to be allowed to choose between two classes.
Here is the context :
If I have two classes : ClassOne and ClassTwo like this :
class ClassOne(models.Model):
something = models.CharField(max_length=255)
class ClassTwo(models.Model):
something = models.CharField(max_length=255)
I need to create an Agenda (where I will put events) which can be linked either to ClassOne or to ClassTwo.
I need to do something like this :
class Agenda(models.Model):
owner = models.OneToOneField( ClassOne or ClassTwo , on_delete=models.CASCADE)
description = models.CharField(max_length=255)
At the end I would like to be allowed to do that :
agenda_one = Agenda(owner = ClassOne, description = "")
agenda_two = Agenda(owner = ClassTwo, description = "")
Do you have an idea about how to achieve this ?

Related

Select Objects related in third table

Say I have the models
class A(models.Model):
class B(models.Model):
class C(models.model):
b = models.ForeignKey(B)
class D(models.Model):
c = models.ForeignKey(C)
a = models.ForeignKey(A)
What would a ORM query look like to select all Bs that are related to C's that are related to a specific A through table D?
As mentioned by the comment on your post you can use the autogenerated related name. But it never hurts to set it yourself.
class C(models.model):
b = models.ForeignKey(B, related_name="c")
class D(models.Model):
c = models.ForeignKey(C, related_name="d")
a = models.ForeignKey(A, related_name="d")
Then:
B.objects.filter(c__d__a=specific_a_obj).distinct()
class C (models.Model):
b = models.ForeignKey(on_delete=models.CASCADE, related_name='c_related')
final query:
c_ids = D.objects.values_list(
'c__id', flat=True).filter(a__id="specific A object id palced here")
query = B.objects.filter(c_related__id__in=c_ids).distinct()

How to get foreign key value from within refereed class

Say I have a model Foo that needs to refer to a value that can be one of several datatypes. To account for that I have several models for each datatype. Is it possible from within the Foo model to create a getValue method that would return the value from the first value method it can find connected with it?
example:
class Foo(models.Model):
def getValue(self):
if self.hasatr('foovalueint'):
return self.foovalueint
elif self.hasatr('foovaluestring'):
return self.foovaluestring
elif self.hasatr('foovaluedatetime'):
return self.foovaluedatetime
class FooValueInt(models.Model):
foo = models.OneToOneField(Foo, on_delete=CASCADE, primary_key=True)
value = models.IntegerField()
class FooValueString(models.Model):
foo = models.OneToOneField(Foo, on_delete=CASCADE, primary_key=True)
value = models.CharField(max_length=50)
class FooValueDateTime(models.Model):
foo = models.OneToOneField(Foo, on_delete=CASCADE, primary_key=True)
value = models.DateTimeField()
Or is there a better way to solve this multiple datatype issue?

Is it possible to have an abstract model inside another abstract model in Django/Djongo?

I'm trying to add a model class with abstract=True in meta to another abstract class.For example,
class MainRecord(models.Model):
date = models.DateTimeField(auto_now_add=True,null=True)
X_data = models.EmbeddedField(
model_container=X,
model_form_class= X_Form,
)
class X(models.Model):
HRCT = models.BooleanField()
Y = models.EmbeddedField(
model_container=Y,
model_form_class=Y_Form,
)
class Meta:
abstract = True
class Y(models.Model):
Y_present = models.BooleanField()
Location = models.EmbeddedField(
model_container=Location,
model_form_class=Location_Form,
)
class Meta:
abstract = True
In Django admin, I'm able to see the embedded fields and it's corresponding checkboxes. I'm able to add/update values for the boolean field HRCT (Embedded from class X) but I'm not able to save the values/updates in the fields embedded from class Y to class X.

Django model inheritance reverse_name issue

Let's start from the botton, this is what I want to achieve
class ClassA(model.Models):
pass
class Class1(model.Models):
fieldX = models.CharField()
class Class2(Class1):
fieldY = models.BooleanField()
# all models are connected, and I prefere to have this situation
# I want to call related ClassA from both Class1 and Class2 using the
# same property
c1 = Class1()
c1.class_a
c2 = Class2()
c2.class_a
# and, at the same time, call both Class1 and Class2 from ClassA
a = ClassA()
a.class_1
a.class_2
To solve this I am duplicating code (and I don't like it):
class Class1(model.Models):
fieldX = models.CharField()
class Class2(model.Models):
fieldY = models.BooleanField()
fieldX = models.CharField()
class ClassA(models.Models):
class_1 = models.OneToOneField(Class1, reverse_name='class_a')
class_2 = models.OneToOneField(Class2, reverse_name='class_a')
The fields are much more than this dummy examples and modify them is quite annoying. How can I do that? I have lots of throubles with "reverse_name" field errors to achieve this, is there a workaroud?

Mongoengine reference another document's field

Is it possible to do something like this?
class Doc1:
fieldd1 = StringField()
class Doc2:
fieldd2 = ReferenceField(Doc1.fieldd1)
Or should I just reference the Doc and then get the field information whenever I need it
This not posible and it is reference to document. To get fieldd1 you must do:
class Doc1(Document):
fieldd1 = StringField()
class Doc2(Document):
fieldd2 = ReferenceField(Doc1)
Doc2.objects.first().fieldd2.fieldd1
If you want just include document to another as part of one document then look at EmbeddedDocument and EmbeddedDcoumentField:
class Doc1(EmbeddedDocument):
fieldd1 = StringField()
class Doc2(Document):
fieldd2 = EmbeddedDcoumentField(Doc1)
Doc2.objects.first().fieldd2.fieldd1
But you always can set own properties:
class Doc1(Document):
fieldd1 = StringField()
class Doc2(Document):
fieldd2 = ReferenceField(Doc1)
#property
def fieldd1(self):
return self.fieldd2.fieldd1
Doc2.objects.first().fieldd1
See documentation: https://mongoengine-odm.readthedocs.org/en/latest/guide/defining-documents.html.