Использование встроенных наборов форм с отношением manytomany

У меня есть модели AbstractUser и Relationship. Модель пользователя имеет много полей через модель отношений

class User(AbstractUser):
    username = models.CharField(
        verbose_name="username", max_length=256, unique=True)
    first_name = models.CharField(verbose_name="first name", max_length=30)
    last_name = models.CharField(verbose_name="last name", max_length=30)
    slug = models.SlugField(max_length=255, unique=True, blank=True)
    date_joined = models.DateTimeField(
        verbose_name="joined date", auto_now_add=True)
    friends = models.ManyToManyField('self', through='Relationship', symmetrical=False,
                                     related_name='following')
    is_active = models.BooleanField(default=True)
    is_superuser = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)

    def __str__(self):
        return str(self.username)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.username)
        super().save(*args, **kwargs)


class Relationship(models.Model):
    from_person = models.ForeignKey(
        User, related_name='from_people', on_delete=models.CASCADE)
    to_person = models.ForeignKey(
        User, related_name='to_people', on_delete=models.CASCADE)

    def __str__(self):
        return f"from {self.from_person} to {self.to_person}"

Как создать инлайн-форму с полями=['from_person' и 'to_person'] для назначения пользователей друг другу Это то, что я пытался сделать, но я не могу иметь оба поля из-за fk_name. Помогите, пожалуйста!

def staff_profile_view(request):
    user = User.objects.get_by_natural_key(request.user)
    AssignFriendsFormSet = inlineformset_factory(
        User, Relationship, fk_name='from_person', fields=('to_person', 'from_person',))

    formset = AssignFriendsFormSet(
        queryset=Relationship.objects.none(), instance=user)

    if request.method == "POST":
        formset = AssignFriendsFormSet(request.POST, instance=user)
        if formset.is_valid():
            formset.save()

    return render(request, 'staff_profile.html',{"formset": formset})

Встроенный набор форм не позволит вам изменить "линию" между моделями, поэтому вы не можете включить 'from_person' в качестве изменяемого поля. В данном случае похоже, что вы пытаетесь получить список людей, следующих за пользователем/заявителем ('from_person') с возможностью их изменения, чтобы они больше не следовали за пользователем.

Инлайновые наборы форм - это всего лишь абстракция, сокращение для определенного типа набора запросов. Вы можете добиться точно такого же эффекта с помощью обычного набора форм, что-то вроде

AssignFriendsFormSet = modelformset_factory(Relationship, fields=('from_person', 'to_person'))
queryset = Relationship.objects.filter(from_person=user)
formset = AssignFriendsFormSet (
        queryset=queryset,
    )

Поле "многие ко многим" на самом деле является просто записью в сквозной таблице, поэтому вы можете обновлять его там.

Вернуться на верх