Home > front end >  How to make individual product subscription for the same user in django
How to make individual product subscription for the same user in django

Time:01-28

I have a website that has some services that has to be subscribed individually. The user has to subscribe the services he wants to avail. Now there are three plans for subscription monthly, quaterly and half-yearly. The user has to choose one of them individually for each service he is opting for.

For example, I have three services civil, tax, criminal. Now a user can choose to subscribe Civil for 1 month and Criminal for 6 month hence these will expire too individually. Based on the services he has choosen he will get menus once he logs in. Below is the approach I took to make the models.

models.py

SUB_CHOICES = (
('monthly', 'monthly'),
('quaterly', 'quaterly'),
('hf', 'half_yearly'),
('anually', 'anually'),
)


class ServiceProduct(models.Model):
    
    title = models.CharField(max_length=50, null = True)
    code = models.IntegerField(null=True, unique= True)
    price = models.DecimalField(max_digits=10,decimal_places=2,null=True)


    def __str__(self):
        return self.title  


class UserSubscription(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    service_choosen = models.ForeignKey(ServiceProduct, on_delete=models.CASCADE, null=True)
    is_active = models.BooleanField(default= False)
    subscribed_on = models.DateTimeField(null=True)
    expiring_on = models.DateTimeField(null=True)
 

Here i connected the usermembership model to customuser with foreign key to make multiple subscription for the same user having is_active class that shall toggle based on the subscription dates and expiring dates. The ServiceProduct models stores the name, prices etc of the service that would be required during checkout

This is how the things are getting stored

But now as I said the user will get menus after login based on what services is active in subscription I am unable to do this in the template. I passed the value from my views as

views.py

 subuser = request.user

 sub = UserSubscription.objects.filter(user = subuser)
 return render(request, 'testpage.html', {'subuser': subuser, 'sub': sub})

But in html i cannot write somthing like

{% for cust in sub %} 
   {% if cust.service_choosen.civil.is_active %} 
          do something... 
   {% endif %}
{% endfor %}

I am sure that I am unable to make the correct models .Therefore please suggest me what will be the right approach to create models that would make this type of subscription method possible.

Desired result:

If the user chooses civil for a month and criminal for 6 months then Civil should be active for him for a month and Criminal should be active for him for 6 months

CodePudding user response:

I believe that is_active would be better as model method. Like this:

def is_active(self):
    return timezone.now() <= self.expiring_on

because it will "update" itself automatically if the subsrciption time will pass.

Share more views.py and I will tell you, how to pass context to html.

CodePudding user response:

in views.py I would first filter UserSubscription to select only active subscriptions

subuser = request.user
sub = UserSubscription.objects.filter(user = subuser, is_active = True)
return render(request, 'testpage.html', {'subuser': subuser, 'sub': sub})

In this way you can simplify your template:

{% for cust in sub %} 
   {% if cust.service_choosen.title == 'civil' %} 
          do something with Civil... 

   {% elif cust.service_choosen.title == 'tax' %}
          do something with Tax... 

   {% elif cust.service_choosen.title == 'criminal' %}
          do something with Criminal... 

   {% endif %}
{% endfor %}

or using code instead of title (suppose codes 1=Civil, 2=Tax and so on):

{% for cust in sub %} 
   {% if cust.service_choosen.code == 1 %} 
          do something with Civil... 

   {% elif cust.service_choosen.code == 2 %}
          do something with Tax... 

   {% elif cust.service_choosen.code == 3 %}
          do something with Criminal... 

   {% endif %}
{% endfor %}

Depending on the output you need, you could also try to generalize (example)

{% for cust in sub %} 
  <a href='#'>Service {{ cust.service_choosen.title }}</a>
{% endfor %}

Also consider that calculating is_active on the fly like suggested by NixonSparrow answer is a best practice

  •  Tags:  
  • Related