Django Использование нескольких (двух) пользовательских типов, расширяющих AbstractUser - PullRequest
0 голосов
/ 02 апреля 2020

ОБНОВЛЕНИЕ : Исправление было найдено. Проблема лежала в Models.py, где мы пытаемся сохранить донор / больницу как экземпляр пользователя, но мы не использовали self.donor (мы использовали донор и предполагали, что он будет связан с созданным экземпляром).

Для нашего проекта у нас есть два типа пользователей: донор и больница. Поэтому мы используем модель User, которая расширяет модель AbstractUser. Модели Donor и Hospital имеют отношения OneToOneField с пользователем и используют аутентификацию пользователя по умолчанию.

Почти все работает нормально. Создание Донора и Больницы работает хорошо, экземпляры добавляются в базу данных, и мы можем войти в систему.

Однако нам нужен объект Донор и его поля в представлении и в шаблоне. У нас есть пользователь, содержащийся в запросе и идентификатор пользователя.

donor = Donor.objects.get(pk=request.user.id)

Или

donor = Donor.objects.filter(donor=request.user).first()

Должен вернуть донора объект, но возвращает None.

Работает для больницы.

Если мы сделаем Donor.objects.all (), нового созданного Донора нет в списке. Однако созданная больница присутствует в списке.

Мы не можем понять, в чем проблема, идентификаторы для донора и пользователя не совпадают.

Большое спасибо за вашу помощь!

Это наши модели:

class User(AbstractUser):
    is_donor = models.BooleanField(default=False)
    is_hospital = models.BooleanField(default=False)


class Donor(models.Model):
    # username, pword, first+last name, email
    donor = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)

    # donor_id = models.IntegerField(auto_created=True, unique=True, null=False, primary_key=True)

    nickname = models.CharField(max_length=40, unique=True)
    phone = models.CharField(max_length=10)
    address = models.CharField(max_length=100)
    blood_type = models.CharField(max_length=3)
    weight = models.IntegerField()
    height = models.IntegerField()
    birth = models.DateField()
    age = models.IntegerField()
    notification = models.BooleanField
    likedStories = models.TextField(default=json.dumps([]))

    def get_age(self, b):
        return int((datetime.date.today() - datetime.datetime.strptime(b, "%Y-%m-%d").date()).days / 365.25)

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

    def new_donor(self, data):

        try:
            MISTAKE # donor = User.objects.create_user(username=data['email'], password=data['password'])
            self.donor = User.objects.create_user(username=data['email'], password=data['password'])
        except IntegrityError:
            return {'error': "email already exists"}
        except:
            return {'error': "something went wrong with email please try again"}

        donor.first_name = data['first_name']
        donor.last_name = data['last_name']
        # donor.nickname = data['nickname']
        donor.is_donor = True

        self.nickname = data['username']
        self.birth = (data['birthday'])
        self.age = self.get_age(self.birth)

        self.address = data['city']

        self.height = data['height']
        self.weight = data['weight']

        self.blood_type = data['blood_type']
        # self.notification = data['notification']

        try:
            # HAS TO BE SELF. THE SAME FOR HOSPITAL
            self.donor.save()
            self.save()
        except IntegrityError:
            donor.delete()
            return {'error': "nickname already exists"}
        except:
            donor.delete()
            return {'error': "something went wrong with nickname please try again"}

        return {'error': None}


class Hospital(models.Model):
    # email, pword
    hospital = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)

    # hospital_id = models.IntegerField(auto_created=True, unique=True, null=False, primary_key=True)
    name = models.CharField(max_length=100)
    location = models.CharField(max_length=300)
    notified_types = models.CharField(max_length=100)
    slug_name = models.SlugField(unique=True)

    # stories = models.ManyToOneRel(Hospital, )

    def save(self, *args, **kwargs):
        self.slug_name = slugify(self.name)
        super(Hospital, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

    def new_hospital(self, data):
        # hospital = User.objects.create_user(data['hospital_name'], data['hospital_email'], data['hospital_password'])
        hospital = User.objects.create_user(username=data['hospital_email'], password=data['hospital_password'])
        hospital.is_hospital = True
        self.name = data['hospital_name']
        self.location = data['location']
        # self.notified_types = data['notif_types']

        hospital.save()
        self.save()

Это модель, где мне нужно получить поле Донора:

@login_required
def app(request):
    context_dict = {}
    # Get 4 most liked stories
    stories = Story.objects.order_by('-likes')[:4]

    # Get all reviews of by the donor
    reviews = Review.objects.all()

    context_dict["stories"] = stories
    context_dict["reviews"] = reviews

    print("Is donor:")
    print(request.user.is_donor)
    print("Is hospital:")
    print(request.user.is_hospital)
    print("All donors:")
    print(Donor.objects.all())
    print("All hospitals:")
    print(Hospital.objects.all())
    print("Has user blood_type attribute:")
    print(request.user._meta.fields)
    # print (Donor.objects.get(donor_id = request.user.id).nickname)
    if request.user.is_hospital:
        hospital = Hospital.objects.filter(hospital=request.user).first()
        print(hospital)
        context_dict["hospital"] = hospital
    else:
        donor = Donor.objects.filter(donor=request.user).first()
        print(donor)
        # context_dict["donor"] = donor

    response = render(request, 'app/app.html', context=context_dict)
    # Return a rendered response to send to the client.
    return response

1 Ответ

0 голосов
/ 02 апреля 2020
donor = Donor.objects.get(donor__user=request.user)

или

donor = Donor.objects.get(donor__user.id=request.user.id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...