Django - ManyToMany через синтетические поля отношений - PullRequest
0 голосов
/ 08 ноября 2018

У меня в приложении есть такие модели:

class User(AbstractUser):
    pass


class MyObject(models.Model):
    name = models.CharField(max_length=200, unique=False, db_index=True)

    related_users = models.ManyToManyField(
        User, through='RelatedUsers', related_name='related_users'
    )


class RelatedUsers(models.Model):
    my_object = models.ForeignKey(
        MyObject, related_name='my_object_related_users'
    )
    user = models.ForeignKey(User)
    type = models.CharField(
        max_length=100,
        choices=RelatedUsersTypes.choices()
    )

    class Meta:
        unique_together = ('user', 'my_object', 'type')


class FunctionalityRelatedUsersTypes(BaseChoiceEnum):
    TYPE_1 = 'TYPE 1'
    TYPE_2 = 'TYPE 2'
    TYPE_3 = 'TYPE 3'
    TYPE_4 = 'TYPE 4'
    TYPE_5 = 'TYPE 5'

Мне интересно, есть ли возможность создать какие-то синтетические отношения на MyObject. Я хотел бы иметь возможность получать пользователей по типу, используя одно поле, например: related_users_type_1. Я также хотел бы использовать его в сериализаторе DRF (чтобы я мог передать только список идентификаторов, и отношение создаст объект Proxy с соответствующим типом).

псевдокод:

related_users_type_1 = models.RelationField(RelatedUsers, filter={'type': 'TYPE_1'})

Пример полезной нагрузки, которую я хочу отправить:

{
    "related_users_type_1": [1, 2, 3],
    "related_users_type_2": [3]
}

Ожидаемый результат:

  • 3 RelatedUsers с TYPE_1
  • 1 RelatedUser с TYPE_2

1 Ответ

0 голосов
/ 08 ноября 2018

Из комментариев, которые у нас были, я думаю, что ваша проблема может быть решена с помощью моделей как таковых:

# just for completeness. should probably use an actual user model
class User (models.Model):
    name = models.CharField(max_length=64)

class MyObject(models.Model):
    name = models.CharField(max_length=64)
    users = models.ManyToMany(User, through='MyObjectUsers', symmetrical=False)

    def add_relations(self, relations):
        for key, list in relations.items():
            for id in list:
                users.add(user=User.objects.get(pk=id), rel_type=key)



class MyObjectUsers(models.Model):
    REL_TYPE_CHOICES=(
        ('TYPE1','TYPE1'),
        ('TYPE2','TYPE2')
    )
    myobject = models.ForeignKey('MyObject', null=True, on_delete=models.SET_NULL)
    user = models.ForeignKey('User', null=True, on_delete=models.SET_NULL)
    rel_type = models.CharField(max_length=32, choices = REL_TYPE_CHOICES)

В документации django показано, как пройти через отношения.

С вышеупомянутой реализацией MyObject вы сможете вызывать .add_relations({'TYPE1':[1,2,3]}) в MyObject экземпляре, чтобы создать необходимые отношения.

Я написал это на своем телефоне, поэтому я не знаю, работает ли он (будет тестировать завтра)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...