django form use excluded field - django

with django 1.5.1 I try to use the django form for one of my models.
I dont want to add the "user" field (Foreignkey) somewhere in the code instead of letting the user deceide whoes new character it is.
My Code:
Model:
class Character(models.Model):
user = models.ForeignKey(User)
creation = models.DateTimeField(auto_now_add=True, verbose_name='Creation Date')
name = models.CharField(max_length=32)
portrait = models.ForeignKey(Portrait)
faction = models.ForeignKey(Faction)
origin = models.ForeignKey(Origin)
The form:
class CreateCharacterForm(forms.ModelForm):
class Meta:
model = Character
fields = ['name', 'portrait', 'faction', 'origin']
The view:
def create_character(request, user_id):
user = User.objects.get(id=user_id)
if request.POST:
new_char_form = CreateCharacterForm(request.POST)
if new_char_form.is_valid():
new_char_form.save()
return HttpResponseRedirect('%s/characters/' % user_id)
else:
return render_to_response('create.html',
{'user': user, 'create_char':new_char_form},
context_instance=RequestContext(request))
else:
create_char = CreateCharacterForm
return render_to_response('create.html',
{'user': user, 'create_char': create_char},
context_instance=RequestContext(request))
I have tried to use a instance to incluse the userid already. i've tried to save the userid to the form before saving it, or changing the save() from my form.
I keep getting the error that character.user cant be null
I have to tell that im pretty new to django and im sure one way or another it should be possible
Can someone please help me out?

Its explained well in document model form selecting fields to use
You have to do something like this in your view
...
if request.POST:
new_char_form = CreateCharacterForm(request.POST)
if new_char_form.is_valid():
#save form with commit=False
new_char_obj = new_char_form.save(commit=False)
#set user and save
new_char_obj.user = user
new_char_obj.save()
return HttpResponseRedirect('%s/characters/' % user_id)
else:
...

Related

Django Form getting invalid

I am newbie to Django. I have some troubles with forms after moving into new verison. Following,
1, The model
class UserProfileDetails(models.Model):
user = models.OneToOneField(User)
profilePicture = models.ImageField('Profile Picture',upload_to='static/ProfilePic/', null=True,blank=True)
def __str__(self):
return self.user.username
2, The form
class imageUploadForm(forms.ModelForm):
class Meta:
model= UserProfileDetails
fields = ['user','profilePicture']
3, And finally the view function
def upload_pic(request):
current_user = request.user
if request.method == 'POST':
form = imageUploadForm(request.POST, request.FILES)
if form.is_valid():
pic = form.cleaned_data['profilePicture']
m = UserProfileDetails(user= current_user.id,profilePicture=pic)
m.save()
else:
raise NotImplemented("What if the user doesn't have an associated profile?")
return HttpResponseRedirect(reverse('polls:profile'))
This code worked with Django 1.8. But after porting to Django 1.10.4, the form is getting invalid. I believe, the problem is with OneToOneField.
IMP: Also, i am using pinax account app for account management.
Why this form is getting invalid?
When you submit the form, it doesn't seem as though a correct input has been given for both fields (user and profile picture). My guess is that you aren't sending through the user in the form which means it is invalid. So you are only uploading the image.
You do not need to have 'user' in the form fields attribute as you already access that in the view with 'request.user'. So remove the 'user' field from the form.
Also, to make sure it is correct, change 'user=current_user.id' to 'user=current_user' so you are match instance with instance rather than instance with id.

How to save username which submits the form?

I'm new to django. I'm trying to create a sports betting game as my first django app.
I have form, using which I'm able to save home goals and away goals for particular game to database, but I can't find a way to insert a username there. Hope you can help!
Here is my view:
#login_required
def group_games(request, groupname):
games = Match.objects.filter(groupname=groupname)
template = loader.get_template('C:\djangoenvs\\typer\\typer\\templates\group_games.html')
username = User.get_username()
for game in games:
game_id = get_object_or_404(Match, pk=game)
form = BetForm(request.POST or None)
if form.is_valid():
print ('valid form')
form.save()
else:
print ('invalid form')
print (BetForm.errors)
context = {
'games': games,
'groupname': groupname,
'form': form,
}
User.get_username() raises the following error:
get_username() missing 1 required positional argument: 'self'
I tried to change it to User.get_username(self) but then:
name 'self' is not defined
Thanks for every answer!
User.get_username()
User represents the complete table, not the record. This is why you get an error.
So remove:
username = User.get_username()
A user might be able to change their username in your application, you can save a foreign key to the user instead. When you save the form do this:
if form.is_valid():
print ('valid form')
bet = form.save(commit=False) # the bet isn't saved just yet
bet.user = request.user # you add the user here
print bet.user.username
bet.save() # finally save the bet in the database
In your Bet model, you need to add a field to record the user. For example:
class Bet(models.Model):
...
user = models.ForeignKey(to=User, related_name="bets", blank=True, null=True)
...

where to hash form data before saving the model in createview in Django?

I am a little confused with where validation of form/model fields can happen in generic CreateView/UpdateView. Consider my hypothetical model below. I want the field secret to be hashed using my custom hashfunction and saved and assume some validation for secret field is done(NOT shown in the example below). My options to do this are:
1) in the model save method (I have not shown this below)
2) in the form's save method (I have shown below)
3) in the form_valid method of AccountCreateView (I have shown below)
4) how can I access the cleaned_data in the generic views (cleaned_data is available
only after form_valid is called)
Which is the right way to do it, both pros and cons. I will use the same form for updateView, in which case I will unhash the secret before displaying its data on the form. where this should happen?
My model:
class Account(models.Model):
user = models.ForeignKey(User)
created = models.DateField(auto_now=True)
secret = models.IntegerField()
My form:
AccountCreateForm(forms.ModelForm):
secret = forms.CharField(max_length=100)
class Meta:
model = MediaContent
exclude = (secret,user,created)
def save(self, user, debate):
obj = super(AccountCreateView, self).save(commit=False)
obj.user = self.cleaned_data['user']
obj.secret = myHashfunction(self.cleaned_data['secret'])
obj.save()
My view:
class AccountCreateView(CreateView):
"""
displays form to create a new search
"""
model = Account
form_class = AccountCreateForm
success_url = reverse_lazy('home')
template_name = 'app/account_form.html'
def form_valid(self, form):
f = form.save(commit=False)
secret=myHashfunction(self.request.POST['secret'])
f.user = self.request.user
f.save()
return super(AccountCreateView,self).form_valid(form)
EDIT:
please see the edit to my model and form. the field I use in form is not the field in model.
It is a new Field, that takes CharField but the model saves as IntegerField. my hashfunciton will convert the charField to IntegerField.
I think in this case Form is the better than ModelForm, as excluding every field on your model makes it redundant. You should then do any additional validation for the un-hashed secret here with clean_secret.
AccountCreateForm(forms.Form):
secret=forms.CharField(max_length=100)
Now, if you are not using the ModelForm anymore, I would suggest using FormView over CreateView as the generic CreateView has become less of a good fit.
class AccountCreateView(FormView):
"""
displays form to create a new search
"""
form_class = AccountCreateForm
success_url = reverse_lazy('home')
template_name = 'app/account_form.html'
def form_valid(self, form):
unhashed_secret = form.cleaned_data['secret']
hashed_secret = myHashfunction(unhashed_secret)
user = self.request.user
# Probably put some extra logic here to check if the user already exists
Account.objects.create(
user=user,
secret=hashed_secret,
)
return super(AccountCreateView,self).form_valid(form)
None of the above. The correct place to do this is in the clean_secret method of the form. That is the place for any field-related validation and conversion. Simply return the hashed value from that method.

'NoneType' object has no attribute 'user'

I'm trying to take input of a domain name (domainNm) and an email address at a domain (emailVerified) and submit them via modelform based off a table [Tld] .
It appears, it is failing to save() the foreign key (from the currently authenticated user)
domain.FKtoClient = user_info
What am I doing wrong here?
forms.py
class SubmitDomain(ModelForm):
domainNm = forms.CharField(initial=u'', label='Enter your domain')
emailVerified = forms.EmailField(label='Email at Domain')
class Meta:
model = Tld #Create form based off Model for Tld
fields = ['domainNm','emailVerified']
def save(self, request=None):
instance = self.cleaned_data
#domain = instance["domainNm"])
domains = Tld.objects.filter(domainNm=instance["domainNm"])
if len(domains) == 0:
domain = Tld()
else:
domain = domains[0]
user_info = request.user
unique_id = int(uuid.uuid4())
domain.generated_hash = str(unique_id)
domain.entered_email = instance["emailVerified"]
domain.domainNm = instance["domainNm"]
domain.FKtoClient = user_info
domain.save()
Thanks!
def save(self, request=None):
You assign a default value of None to request in the definition of save, so what happens when the caller of save doesn't pass an instantiated request?
user_info = request.user #request is None here
That will throw the error you see. To mitigate, add a simple if request is not None or similar statement.
EDIT
After seeing your views.py, you are passing request.POST to SubmitDomain's __init__ magic method, which you have not defined. The way you have your modelform defined above, you would have to pass the request to save(), not __init__(), i.e.
form.save(request)

Username already exists, when want to update userprofile in django

Whenever I try try to update a userprofile on django powered web, I get the error: "username already exists, please provide another one." I am trying to get it to recognize the authenticated user. Although every other thing works, it will not update until I specify a new username.
views.py
#login_required
def editprofile(request):
registeredmember = request.user.get_profile()
if request.method == 'POST':
userprofile_edit = RegistrationForm(request.POST, instance = registeredmember)
if userprofile_edit.is_valid():
userprofile_edit.save()
return HttpResponseRedirect('/profile/')
else:
userprofile_edit = RegistrationForm(instance = registeredmember)
return render_to_response('carloan/editprofile.html', {'userprofile_edit': userprofile_edit}, context_instance=RequestContext(request))
You have to exclude the username field when you are Editing the profile.
Something like this in your RegistrationForm.
class RegistrationForm(forms.form):
#other code
class Meta:
exclude = ['username',]
You can add multiple field names which you don't want to be included in the form