chobo
chobo

Reputation: 4862

Django models.py error(about ManyToManyField)

from django.db import models
from django.contrib.auth.models import User

class WorkDailyRecord(models.Model):
    user = models.ForeignKey(User)
    date = models.DateTimeField(auto_now=True)
    contents = models.TextField()
    check_user = models.ManyToManyField(User)
    target_user = models.ManyToManyField(User)

    ONGOING_OR_END =(
            ('ing', '진행중'),
            ('end', '완료'),
        )


    ongoing_or_end = models.CharField(
            max_length=3,
            choices=ONGOING_OR_END,
            default='ing',
        )

I write that code, then I'm give error...

So I search the Internet, and I find out that I must use 'related_name' attribute.

But I don't know why I must use that attr??

Why??

Upvotes: 0

Views: 98

Answers (1)

By setting up an M2M to the User model, User instances will have an automatic workdailyrecord_set attribute set on them. Since you need 2 accessors, django complains since it can't set workdailyrecord_set twice.

If they allowed it, it would be very confusing indeed, as who knows what user.workdailyrecord_set would return in that case.

You need to give it a related_name to differentiate between the two relationships pointing to User.

target_user = models.ManyToManyField(User, related_name='workdailyrecord_target')
check_user = models.ManyToManyField(User, related_name='workdailyrecord_check')

This way, User instances will have a workdailyrecord_target reverse manager which will only query WorkDailyRecord objects related to User by the target_user relationship.

e.g.

User.objects.latest('id').workdailyrecord_target.all()  
#  all WorkDailyRecords where user is referenced by 'target_user'

User.objects.latest('id').workdailyrecord_check.all()
 #  all WorkDailyRecords where user is referenced by 'target_check'

Unfortunately, you cannot disable this feature even using django's documented related_name='+' feature when it comes to M2Ms. Don't ask me why :)

Upvotes: 3

Related Questions