Search code examples
djangodjango-viewsforeign-keysslug

Field 'id' expected a number but got <property object at 0x03F53528>. -


I am building a registration app that needs to register people based on the specific User model instance. My urls are based on the slugs of my users and based on those values people can register at a specific user. For example, people can register at Apples or at Bananas. The form that is posted contains the specific user.id which is passed to the People Model alongside the filled in form fields.

Now I am getting the following error which I can't get my head around:

Field 'id' expected a number but got <property object at 0x03CC54B0>.

My urls:

app_name = 'register'

urlpatterns = [
    path('<slug>/contact/', ContactView.as_view(), name='contact'),
    path('<slug>/thanks/', ThanksView.as_view(), name='thanks'),
]

My models:

class Bedrijf(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    bedrijfsnaam = models.CharField(max_length=80, null=True)
    slug = models.SlugField(max_length=30)

class Bezoeker(models.Model):
    bedrijf = models.ForeignKey(Bedrijf, on_delete=models.CASCADE)
    voornaam = models.CharField(max_length=30)
    achternaam = models.CharField(max_length=50)

My Views

class ContactView(CreateView):
    template_name = 'register/contact.html'
    form_class = BezoekerForm

    def get_success_url(self):
        return reverse('bedankt', kwargs={'slug': Bedrijf.slug})

    def get(self, request, *args, **kwargs):
        form = BezoekerForm
        slug = get_object_or_404(Bedrijf, slug=Bedrijf.slug)
        context = {'form': form, 'slug': slug}
        return render(self, self.template_name, context)

    def post(self, request, *args, **kwargs):
        bedrijf = Bedrijf.objects.get(pk=Bedrijf.pk)
        if request.method == 'POST':
            form = self.form_class(request.POST)
            if form.is_valid():
                new_register = form.save(commit=False)
                new_register.bedrijf = bedrijf.pk
                new_register.save()
            return reverse('bedankt')

What am I missing here?


Solution

  • The query Bedrijf.objects.get(pk=Bedrijf.pk) does not make much sense, since Bedrijf is the class, so Bedrijf.pk is just a property.

    You can make use of get_object_or_404 to retrieve the corresponding Bedrijf, for the slug URL parameter:

    class ContactView(CreateView):
        template_name = 'register/contact.html'
        form_class = BezoekerForm
    
        def get(self, request, *args, **kwargs):
            form = BezoekerForm()
            slug = self.kwargs['slug']
            bedrijf = get_object_or_404(Bedrijf, slug=slug)
            context = {'form': form, 'slug': slug}
            return render(self, self.template_name, context)
    
        def post(self, request, *args, **kwargs):
            slug = self.kwargs['slug']
            bedrijf = get_object_or_404(Bedrijf, slug=slug)
            if request.method == 'POST':
                form = self.form_class(request.POST, request.FILES)
                if form.is_valid():
                    form.instance.bedrijf = bedrijf
                    form.save()
                return reverse('bedankt', slug=slug)
            return render(self, self.template_name, {'slug': slug, 'form': form})

    But this actually does all the work itself. One uses class-based views like a CreateView to remove a lot of boilerplate code:

    class ContactView(CreateView):
        template_name = 'register/contact.html'
        form_class = BezoekerForm
    
        def get_context_data(self, *args, **kwargs):
            context = super().get_context_data(*args, **kwargs)
            context.update(
                slug=self.kwargs['slug'],
                bedrijf = get_object_or_404(Bedrijf, slug=slug)
            )
            return context
    
        def get_success_url(self):
            return reverse('bedankt', kwargs={'slug': self.object.bedrijf.slug})
    
        def form_valid(self, form):
            form.instance.bedrijf = get_object_or_404(Bedrijf, slug=self.kwargs['slug'])
            return super().form_valid(form)