The Messie
The Messie

Reputation: 103

Django multiple Many2Many relationships

I have created a model where I define a Place, which has several properties (M2M) and each property has several choices. A user is able to vote for one or more of the choices, therefore I define a M2M relationship from the choices to a user. However I do not achieve the required functionality, as the user is connected only to the choices and not to the specific place that has the choices. my model is as follows:

class Place(models.Model):
    StoreName=models.CharField(max_length=200)
    Pic=models.ImageField(upload_to="media",blank=True,null=True)
    Address=models.CharField(max_length=200)

    def __unicode__(self):
        return self.StoreName   

class TypeProperty(models.Model):
    Place = models.ManyToManyField(Place)
    TypePropertyName=models.CharField(max_length=42)
    def __unicode__(self):
        return self.TypePropertyName

class TypeChoices(models.Model):
    TypeProperty = models.ForeignKey(TypeProperty)
    TypeChoiceName=models.CharField(max_length=42)
    UserVoted=models.ManyToManyField(User,blank=True,null=True)

How can I achieve the functionality

A User has voted for the Choice that for the specific Place

Upvotes: 0

Views: 145

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239220

From User you can get TypeChoices:

user_instance.typechoices_set.all()

Then, you can loop through each TypeChoice and access the Place queryset through the TypeProperty attribute:

typechoice_instance.TypeProperty.Place.all()

Then you would need to loop through each Place to do whatever.

Now, looking at that, it should be immediately apparent that there's some serious flaws here. The code makes no sense, and it's not readable. This is why coding conventions exist. Please give the Python Style Guide (PEP8) a thorough read.

In particular to your code here, attributes on a class should be all lower-case and words in the attribute's name should be separated by underscores, i.e. store_name NOT StoreName.

Then, attribute names should parallel what they represent: Place makes no sense for a field that will return multiple places. Name it places to indicate that it returns multiple items (and in particular returns a queryset rather than a model instance).

UPDATE

If you want that, then you need to work backwards and select the TypeChoices:

TypeChoices.objects.filter(UserVoted=some_user, TypeProperty__Place=some_place)

Upvotes: 2

Related Questions