Есть ли способ сравнить два поля в двух моделях и сохранить поле в первой модели в Django?
class Register(models.Model):
prollno=models.CharField(max_length=8)
full_name=models.CharField(max_length=100)
drollno=models.CharField(max_length=9)
email=models.EmailField()
gender=models.CharField(max_length=7,default="Male")
programme=models.CharField(max_length=100)
course=models.CharField(max_length=100)
yearofstudy=models.CharField(max_length=5)
phone=models.BigIntegerField()
city=models.TextField()
pincode=models.IntegerField()
address=models.TextField()
isblacklisted=models.BooleanField(default=False)
class Blacklist(models.Model):
prollno=models.ForeignKey(Register)
full_name=models.CharField(max_length=100)
email=models.EmailField(max_length=55)
phone=models.BigIntegerField()
У меня есть две модели Register и Blacklist, и я должен сравнить prollno моделей Register и Blacklist, и если значения, хранящиеся в обеих prollno, одинаковы, то я должен сохранить поле isblacklisted модели Register равным True.
Поле prollno в классе модели Blacklist связано со всем экземпляром модели Register.
Следовательно, я бы предложил вам изменить имя атрибута prollno в Blacklist на что-то вроде register. Тогда доступ к значению атрибута prollno можно будет получить через register.prollno.
Теперь, когда весь экземпляр Register связан с вашим экземпляром Blacklist, вам не нужно использовать атрибут isblacklisted в классе Register, так как это создаст круговой шаблон без всякой причины.
Следовательно, добавление полей, повторяющих поля full_name, email и phone в классе Blacklist не должно быть необходимым, если они будут иметь те же значения, что и в классе Register.
Итак, если вы решили:
A. только пометить модель Register как занесенную в черный список и не добавлять никакой дополнительной информации
Тогда можно не создавать модель Blacklist и просто иметь атрибут isblacklisted в модели Register.
Из сериализатора модели Register (скажем, RegisterSerializer) можно создать набор представлений черного списка для получения записей, занесенных в черный список, следующим образом:
from rest_framework import viewsets
class BlacklistViewSet(viewsets.ModelViewSet):
queryset = models.Register.objects.filter(isblacklisted=True)
serializer_class = serializers.RegisterSerializer
filter_backends = (DjangoFilterBackend,)
filterset_fields = "__all__"
B. иметь обе модели Register и Blacklist в models.py с дополнительными атрибутами в классах.
Вы захотите удалить атрибут isblacklisted из класса Register, чтобы избавиться от круговой схемы, как описано выше.
Теперь вы можете получить доступ к экземплярам Register, занесенным в черный список, путем сериализации Blacklist модели.
(1) Если вы все еще хотите изменить is_blacklisted атрибут
Тогда ваши данные должны измениться при создании Blacklist экземпляра модели.
Предполагая, что prollno передается в BlacklistSerializer, мы можем переопределить код сериализаторов следующим образом:
from rest_framework.serializers import ModelSerializer
from django.core.exceptions import ObjectDoesNotExist
class BlacklistSerializer(ModelSerializer):
def create(self, validated_data):
try:
register_instance = models.Register.objects.get(
prollno=validated_data['prollno']
)
except ObjectDoesNotExist:
pass
else:
instance, created = models.Blacklist.objects.get_or_create(
register=register_instance
)
if created:
register_instance.is_blacklisted = True
register_instance.save()
(2) Если вы хотите выполнить это действие при обновлении информации Blacklist
Тогда мы можем просто предположить, что создан экземпляр Blacklist без связанного экземпляра Register. Это не кажется хорошей реализацией и, вероятно, потребуется добавить атрибут типа blank=True к атрибуту as:
class Blacklist(models.Model):
register=models.ForeignKey(Register, blank=True)
Итак, функция обновления будет выглядеть так:
def update(self, instance, validated_data):
try:
register_instance = models.Register.objects.get(
prollno=validated_data['prollno']
)
except ObjectDoesNotExist:
pass
else:
instance.register=register_instance
instance.save()
register_instance.is_blacklisted = True
register_instance.save()