Search code examples
djangogenericsdjango-modelsdjango-contenttypes

Generics in Django


Could someone translate this Java Pseudo code with generics to Django models? I don't understand the content type concept. It would also be possible to leave out the map and just have a list of KeyValuePairs or KeyValueExamples.

class Dictionary<T extends KeyValuePair>

class KeyValuePair
    String key
    String value

class KeyValueExample extends KeyValuePair
    String example

class Container
    Dictionary<KeyValuePair> itemsOne
    Dictionary<KeyValueExample> itemsTwo

Solution

  • Django's contenttypes doesn't have anything common with generics from Java. Python has a dynamic type system so there is no need for generics.

    This means that you can put any object of any class into the dictionary:

    class Container(object):
    
        def __init__(self):
            self.itemsOne = {}
            self.itemsTwo = {}
    
    container = Container()
    container.itemsOne['123'] = '123'
    container.itemsOne[321] = 321
    container.itemsTwo[(1,2,3)] = "tuple can be a key"
    

    If you want to implement your classes in django models then code could be something like this:

    class KeyValuePairBase(models.Model):    
        key = models.CharField(max_length=30)
        value = models.CharField(max_length=30)    
        class Meta:
            abstract = True    
    
    class KeyValuePair(KeyValuePairBase):
        pass    
    
    class KeyValueExample(KeyValuePairBase):
        example = models.CharField(max_length=30)    
    
    class Container(models.Model):    
        items_one = models.ManyToManyField(KeyValuePair)
        items_two = models.ManyToManyField(KeyValueExample)
    
    # usage of these models
    
    kvp = KeyValuePair.objects.create(key='key', value='value')
    kve = KeyValueExample.objects.create(key='key', value='value',
                                         example='Example text')
    
    container = Container.objects.create()
    container.items_one.add(kvp)
    container.items_two.add(kve)