0

I currently have a model form that submits an entered domain to the db.

The problem I'm encountering is, I need to save the currently logged in user's ID (PK from the django.auth table) when a domain is submitted to satisfy a PK-FK relationship on the db end.

I currently have:

class SubmitDomain(ModelForm):
    domainNm = forms.CharField(initial=u'Enter your domain', label='')
    FKtoClient = User.<something>

    class Meta:
        model = Tld #Create form based off Model for Tld
        fields = ['domainNm']

def clean_domainNm(self):
    cleanedDomainName = self.cleaned_data.get('domainNm')
    if Tld.objects.filter(domainNm=cleanedDomainName).exists():
        errorMsg = u"Sorry that domain is not available."
        raise ValidationError(errorMsg)
    else:
        return cleanedDomainName

and views.py

  def AccountHome(request):
    if request.user.is_anonymous():
        return HttpResponseRedirect('/Login/')

    form = SubmitDomain(request.POST or None) # A form bound to the POST data

    if request.method == 'POST': # If the form has been submitted...
        if form.is_valid(): # If form input passes initial validation...
            domainNmCleaned = form.cleaned_data['domainNm']  ## clean data in dictionary
            clientFKId = request.user.id
            form.save() #save cleaned data to the db from dictionary`

            try:
                return HttpResponseRedirect('/Processscan/?domainNm=' + domainNmCleaned)
            except:
                raise ValidationError(('Invalid request'), code='300')    ## [ TODO ]: add a custom error page here.
    else:
        form = SubmitDomain()

    tld_set = request.user.tld_set.all()

    return render(request, 'VA/account/accounthome.html', {
        'tld_set':tld_set, 'form' : form
    })

The problem is it gives me an error of: (1048, "Column 'FKtoClient_id' cannot be null"), very odd thing happening, for the column FKtoClient, its trying to submit: 7L instead of 7(the PK of this user's record). Any ideas?

If someone can please help, I would really appreciate it

CodeTalk
  • 3,571
  • 16
  • 57
  • 92
  • 1
    Don't worry about `7L`, see [this question](http://stackoverflow.com/questions/11764713/why-do-integers-in-database-row-tuple-have-an-l-suffix) for more info. – Alasdair Nov 01 '13 at 00:43

3 Answers3

2

Firstly, remove FKtoClient from your form. You need to set the user in your view where you can yes the request object. It's not possible to set an attribute on the form that automatically sets the current user.

When instantiating your form, you can pass a tld instance which already has the user set.

def AccountHome(request):
    # I recommend using the login required decorator instead but this is ok
    if request.user.is_anonymous():
        return HttpResponseRedirect('/Login/')

    # create a tld instance for the form, with the user set
    tld = Tld(FKtoClient=request.user)
    form = SubmitDomain(data=request.POST or None, instance=tld) # A form bound to the POST data, using the tld instance

    if request.method == 'POST': # If the form has been submitted...
        if form.is_valid(): # If form input passes initial validation...
            domainNm = form.cleaned_data['domainNm']
            form.save() #save cleaned data to the db from dictionary

            # don't use a try..except block here, it shouldn't raise an exception
            return HttpResponseRedirect('/Processscan/?domainNm=%s' % domainNm)
    # No need to create another form here, because you are using the request.POST or None trick
    # else:
    #    form = SubmitDomain()

    tld_set = request.user.tld_set.all()

    return render(request, 'VA/account/accounthome.html', {
         'tld_set':tld_set, 'form' : form
    })

This has an advantage over @dm03514's answer, which is that you can access the user within form methods as self.instance.user if required.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • I don't understand your question. My example above will set `tld.user` to be the user making the request. If you want to access the user id, use `request.user.id`. There is no way to declare `FKtoClient` on the form class, and have it magically update the form with the user in the current request. To access the user, you have to access `request.user` in a view (or suitable model admin method), and then update the set the form or instance. – Alasdair Oct 31 '13 at 16:40
  • Could you show an example of use with request.user.id please? – CodeTalk Oct 31 '13 at 17:45
  • I can't help you any more because I don't understand what you are trying to do. If you want the `tld.user` field to be set to the current user, then my example will work. – Alasdair Oct 31 '13 at 18:16
  • As the question states: I'm simply trying to get the currently authenticated user's (id) from the Django Auth "User" table. Each record in User Table has a primary key associated within a column named 'id'. Does that make sense? – CodeTalk Oct 31 '13 at 22:03
  • As we've already said, the id of the current user is `request.user.id`. However, that doesn't seem to solve your problem, so it's not clear what you want. I'm afraid I can't help you any more, hope you manage to figure it out. – Alasdair Oct 31 '13 at 22:09
  • Can you explain which library needs to be imported for request.user.id ? If I use this, its an uninitialized import since it needs to have something imported when used in forms.py – CodeTalk Oct 31 '13 at 22:11
  • 1
    It's not a library, it's the `request` object in a view. Both me and @dm03514 have already given you examples of views that do what we think you want. – Alasdair Oct 31 '13 at 22:24
  • much appreciated. I guess I was attempting to implement in an area (forms.py) where it wasn't possible. Appreciate the explanation – CodeTalk Oct 31 '13 at 23:42
  • One thing to mention though is - when the form is submitted, it complains that the FK cannot be empty. See updated code above – CodeTalk Nov 01 '13 at 00:09
  • Very close, but its submitting a value of 7L for the FKtoClient field, when it should be 7 – CodeTalk Nov 01 '13 at 00:21
  • Anyway possible you could help me out a bit more? I really need it – CodeTalk Nov 01 '13 at 00:36
  • I've adjusted my example to use the view you added to your question. – Alasdair Nov 01 '13 at 00:41
  • I thoroughly read your answer and thanks for getting back to me. I implemented the code properly and am getting: `'user' is an invalid keyword argument for this function'` on `'tld = Tld(user=request.user)` any idea why? – CodeTalk Nov 01 '13 at 01:01
  • The answer assumed that your `Tld` model had a foreign key to the `User` model named `user`. I see that you've named the foreign key `FKtoClient`, so I've updated the answer. You should consider renaming the field to `user`, it's much more idiomatic. – Alasdair Nov 01 '13 at 01:18
1

If you want to Require that a user be logged in to submit a form, you could do something like:

@login_required # if a user iS REQUIRED to be logged in to save a form
def your_view(request):
   form = SubmitDomain(request.POST)
   if form.is_valid():
     new_submit = form.save(commit=False)
     new_submit.your_user_field = request.user
     new_submit.save()
dm03514
  • 54,664
  • 18
  • 108
  • 145
  • That is not the request. The User is already authenticated. He/she is submitting a form and on submission it currently submits the form entry, but it also has to include the id of the already logged in user. Does that make sense? – CodeTalk Oct 31 '13 at 15:59
  • This example view shows you how to set the user when you are saving a form. You should be able to adjust your view to do the same thing. If you are trying to do this in the Django admin rather than a view, you should update your question to say so. – Alasdair Oct 31 '13 at 16:51
0

You can get the logged in user from the request object:

current_user = request.user
Daniel Wärnå
  • 678
  • 8
  • 17