0

I am fairly new to Django. So trying to use inbuilt functionalities instead of overriding the functions. I have established ManyToMany relationship between user and service.

Means a user can have many services and a service can be obtained by many users. (Not sure if I am correct)

Following are my models

Userdata

from django.db import models
from django.contrib.auth.models import User
from services.models import Services

class Userdata(models.Model):
    username=models.OneToOneField(User,on_delete=models.CASCADE)
    tel=models.CharField(max_length=10,unique=True)
    address=models.CharField(max_length=100,null=True,blank=True)
    city=models.CharField(max_length=10,null=True,blank=True)
    zipcode=models.CharField(max_length=6,null=True,blank=True)
    services=models.ManyToManyField(Services,through='dashuser.UpcomingUserServices')

Services

from django.db import models

class Services(models.Model):
    sname=models.CharField(max_length=20)
    scost=models.IntegerField()

    def __str__(self):
        return self.sname

UpcomingUserService

from django.db import models
from services.models import Services
from log.models import Userdata

class UpcomingUserServices(models.Model):
    userdata=models.ForeignKey(Userdata,on_delete=models.CASCADE)
    service=models.ForeignKey(Services,on_delete=models.CASCADE)
    name=models.CharField(max_length=20)
    phone=models.CharField(max_length=10)
    date=models.DateField()
    address=models.CharField(max_length=100)
    zipcode=models.IntegerField()
    remarks=models.CharField(max_length=100,null=True,blank=True)

ServiceForm

from django import forms
from .models import UpcomingUserServices

class ServiceForm(forms.ModelForm):
    service=forms.ModelMultipleChoiceField(Services.objects.all(),widget=forms.CheckboxSelectMultiple())

    class Meta:
        model=UpcomingUserServices
        exclude=['userdata']

view

def book(request):
    if request.method=='POST':
        serlist=[]
        f=ServiceForm(request.POST)
        if f.is_valid():
            s=f.save(commit=False)
            u=request.user
            u1=Userdata.objects.get(username_id=u.id)
            s.userdata_id=u1.id
            f.save()
            f.save_m2m()
            return HttpResponse('Done')
        else:
            return render(request,'ns.html',{'f':f})
    else:
        u=request.user
        u1=Userdata.objects.get(username_id=u.id)
        i={
            'name':u.first_name+" "+u.last_name,
            'phone':u1.tel,
            'email':u.email,
            'address':u1.address,
            'zipcode':u1.zipcode
        }
        f = ServiceForm(initial=i)
        return render(request,'ns.html',{'f':f})
# ns.html is where the form is rendered

When the form is submitted, I get following error

ValueError at /user/book
Cannot assign "<QuerySet [<Services: Lawn Mowing>, <Services: Lawn Fertilization>]>": "UpcomingUserServices.service" must be a "Services" instance

(/user/book is view's URL)

TrackBack:

Traceback:

File "F:\My Projects\login\venv\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "F:\My Projects\login\venv\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "F:\My Projects\login\venv\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "F:\My Projects\login\venv\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)

File "F:\My Projects\login\dashuser\views.py" in book
  63.         if f.is_valid():

File "F:\My Projects\login\venv\lib\site-packages\django\forms\forms.py" in is_valid
  185.         return self.is_bound and not self.errors

File "F:\My Projects\login\venv\lib\site-packages\django\forms\forms.py" in errors
  180.             self.full_clean()

File "F:\My Projects\login\venv\lib\site-packages\django\forms\forms.py" in full_clean
  383.         self._post_clean()

File "F:\My Projects\login\venv\lib\site-packages\django\forms\models.py" in _post_clean
  398.             self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)

File "F:\My Projects\login\venv\lib\site-packages\django\forms\models.py" in construct_instance
  60.             f.save_form_data(instance, cleaned_data[f.name])

File "F:\My Projects\login\venv\lib\site-packages\django\db\models\fields\__init__.py" in save_form_data
  854.         setattr(instance, self.name, data)

File "F:\My Projects\login\venv\lib\site-packages\django\db\models\fields\related_descriptors.py" in __set__
  210.                     self.field.remote_field.model._meta.object_name,

Exception Type: ValueError at /user/book
Exception Value: Cannot assign "<QuerySet [<Services: Lawn Mowing>, <Services: Lawn Fertilization>]>": "UpcomingUserServices.service" must be a "Services" instance.

1 Answers1

0

You use UpcomingUserServices model by intermediate model. So UpcomingUserServices model must take one user and one service. But your ServiceForm took multiple services by forms.ModelMultipleChoiceField.

I know what you're trying to implement. But that's not correct.

You are using intermediate table. So check intermediary many to many and similar case question

Jrog
  • 1,469
  • 10
  • 29
  • As you know what I am trying to do.. Please give some way to implement it. One doubt: When i use ModelChoiceField instead of ModelMultipleChoiceField, it works correctly except for the first service selected, it takes correct date but for other selected, it takes first date possible.. Why so? Any way to correct it? – Raghav Thakkar Jan 11 '19 at 09:08
  • @RaghavThakkar You need to understand about `Many to Many` relationship. I already said `UpcomingUserServices` model must take only one `service`. But `ModelMultipleChoiceField` give multiple `service` instance. Please read my attached article carefully and understand how it differs from your code. You have to figure out how to solve it on your own. – Jrog Jan 11 '19 at 09:22
  • Hi, I found a way by using save method inside for loop (for every service object) and it's working fine. Is it the ok or any better solution exists? – Raghav Thakkar Feb 05 '19 at 04:28