'Is there anyway to compare two fields in two models and store a field in the first model in 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()
  

I have two models Register and Blacklist and I have to compare the prollno of Register and Blacklist and if the values stored in both prollno are same, then I have to save the field isblacklisted of Register Model to True.



Solution 1:[1]

The prollno field in the model class Blacklist is linked to the entire Register model instance.

Hence, I would suggest you to change the attribute name prollno in Blacklist to something like register. The prollno attribute's value can then be accesssed via register.prollno.

Now, when you have the entire Register instance linked to your Blacklist instance, you shouldn't need to use a isblacklisted attribute in class Register as that would create a circular pattern for no reason.

Hence, adding fields repetitive fields like full_name, email, and phone in class Blacklist should not be necessary if they are going to have the same values as that in the class Register.

So, if you choose to:

A. only mark the model Register as blacklisted and not add any additional info

Then, you can avoid creating the model Blacklist and just have the isblacklisted attribute in model Register.

A Blacklist Viewset can be created from the serializer of the model Register (say, RegisterSerializer) to fetch records that are blacklisted as follows:

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. have both the models Register and Blacklist in models.py with additional attributes in the classes.

You would want to remove the isblacklisted attribute from class Register to get rid of the circular pattern as described above.

Now, you can access the Register instances that are blacklisted by serializing the Blacklist model.

(1) If you still wish to change the is_blacklisted attribute

Then, your data should change while creating the Blacklist model instance.

Assuming the prollno is passed to the BlacklistSerializer, we can override the serializers code as:

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) If you want to perform this action while updating the information of Blacklist

Then, we can just assume there is a Blacklist instance created without any Register instance linked. This does not seem to be a great implementation and would probably need an attribute like blank=True added to the attribute as:

class Blacklist(models.Model):    
  register=models.ForeignKey(Register, blank=True) 

So, the update function would be as:

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()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tanya Jain