Home > Software design >  How to model this field/relation using Django
How to model this field/relation using Django

Time:04-12

I'm creating an API using the django rest framework want to store an array of pictures inside my user model. For each picture I should have an URL and boolean flag indicating whether it is the display picture or not. There should be atleast 2 and maximum 6 pictures. One and only one of those pictures should have the display_picture_flag set as true. What would be a good way to model this.

My approach (Might not be best) -

  1. I'm thinking of creating another model class with user id from user class as the foreign key. It will have an URL field and a boolean field aswell. My doubts with this are,
  • How will I validate number of objects as lying in [2,6]. Validating that only one flag is true.
  • Creating [2,6] objects at the same time (single Create API call).
  1. Using JSON field. probably store as dictionary with URL mapped to flag.
  • Again, confused with validations.

Please suggest better approaches, or expand upon my approaches. Thanks!

CodePudding user response:

Ok so I think you can write you validation login for number of pictures in your model.save method. And for display_picture_flag field you can maintain a table which will have two field (CurrentActivePicModel).

For example:

  class PictureModel(models.Model):
       user = models.ForeignKey(User, on_delete=CASCADE)
       url_value = models.URLField()
       display_picture_flag = models.BooleanField(default=False)

  class CurrentActivePicModel(models.Model):
       user = models.ForeignKey(User, on_delete=CASCADE)
       picture = models.ForeignKey(PictureModel, on_delete=CASCADE)
       
  1. user
  2. the picture for which display_picture_flag = True

whenever you get new input (picture) having display_picture_flag = True, you can check in CurrentActivePicModel which picture is set to True and then you can set it false or whatever you want and then save it.

Again, you can check for number of existing pictures in your save() method of model and any existing CurrentActivePicModel. I can provide you the code if you want.

CodePudding user response:

I think this should solve your query

 class PictureModel(models.Model):
      user = models.ForeignKey(User, on_delete=CASCADE)
      url_value = models.URLField()
      display_picture_flag = models.BooleanField(default=False)

      # overriding default save method
      def save(self, *args, **kwargs):

          # check count of pictures for current user
          pic_cnt =  PictureModel.objects.filter(user=self.user).count()
          if pic_cnt > 7:
              return {'error':"some error line"}
          else:
              # saving picture for the current user
              saveObj = super().save(*args, **kwargs)
        
              # if this picture is to be set true then update 
              # CurrentActivePicModel to this picture
              if self.display_picture_flag:
                  print(CurrentActivePicModel)
                  active_pic_obj = 
                  CurrentActivePicModel.objects.filter(user=self.user).first()

                  # if any true picture is available for this user if none 
                  #create new entry of CurrentActivePicModel with current 
                  #picture
                  if active_pic_obj is not None:
                      active_pic_obj.picture = self
                      active_pic_obj.save()
                  else:
                      currObj = CurrentActivePicModel(user=self.user, 
                      picture=self)
                      currObj.save()
        


   class CurrentActivePicModel(models.Model):
       user = models.ForeignKey(User, on_delete=models.CASCADE)
       picture = models.ForeignKey(PictureModel, on_delete=models.CASCADE)
  • Related