I'm developing a small exchange system and I want to give everyone who joins this app a random amount (1-10) of btc. When someone compiles the register form succesfully, recives a random amount of Btc in the wallet. That is my code but doesn't work
models.py
class Profile(models.Model):
_id = ObjectIdField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
wallet = models.FloatField()
class Order(models.Model):
_id = ObjectIdField()
profile = models.ForeignKey(User, on_delete=models.CASCADE)
datetime = models.DateTimeField(auto_now_add=True)
price = models.FloatField()
quantity = models.FloatField()
views.py
def registerPage(request):
bonus = randint(1,10)
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.wallet = bonus
form.save()
return redirect('login')
contex = {'form':form}
return render(request, 'app/register.html', contex)
forms.py
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
I don't know if is't important but I'm working with Mongodb. Thanks
Try this:
def registerPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
new_user = form.save()
bonus = random.randint(1,10)
new_profile = Profile.objects.create(user=new_user, wallet=bonus)
new_profile.save() # unnecessary after calling `create` but I still do this just in case :)
return redirect('login')
else:
form = CreateUserForm()
contex = {'form':form}
return render(request, 'app/register.html', contex)
Related
I have model from which I created a ModelForm:
models.py:
class City(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return f'{self.name}'
class Profile(models.Profile):
name = models.CharField(max_length=50)
user = models.OneToOneField(User, on_delete=models.CASCADE, unique=False)
location = models.ForeignKey('City', on_delete=models.SET_NULL, blank=True, null=True)
forms.py
from django import forms
from .models import Profile, City
class LocationField(forms.CharField):
def clean(self, value):
try:
city = City.objects.get(name=value)
except ObjectDoesNotExist:
city = City.objects.create(name=value)
return city
class ProfileForm(forms.ModelForm):
location = LocationField()
class Meta:
model = Profile
exclude = ['user']
views.py
def profile_update_view(request):
template_name = 'profiles/update.html'
user = request.user
profile = Profile.objects.get(user__id=user.id)
if request.method == 'GET':
form = ProfileForm(instance=profile)
else:
form = ProfileForm(request.POST, instance=profile)
if form.is_valid():
obj = form.save(commit=False)
obj.user = user
obj.save()
return redirect('profile_view')
context = {'form': form}
return render(request, template_name, context=context)
When I'm saving form, I'm satisfied how it's working, but when I load form again to update in, it fills LocationField() as an City pk integer, but I want it to load name instead. Is there a way to do this?
I've added in views.py:
if request.method == 'GET':
initial = {}
if profile.location:
initial = {'location': profile.location.name}
form = ProfileForm(instance=profile, initial=initial)
now it's working. But it's some workaround. I've thought there is some parameter maybe
I have models like this:
class Projects(models.Model):
project = models.CharField(max_length=150, blank=True, null=True)
def __str__(self):
return self.project
class Profile(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
project = models.ForeignKey(Projects, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.user.username
I also made a form in which I want to change current Project assigned Profile:
class ProjectForm(ModelForm):
class Meta:
model = Profile
fields = [
'project'
]
My view looks like this:
def change_project(request, user):
user = User.objects.filter(username=user)[:1].get()
profile = Profile.objects.get(user=user)
form = ProjectForm(request.POST, instance=profile)
if request.method == 'POST':
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'datafiller/change_project.html', context)
I can change the project using this form, but every time I want to do it again the form looks like this
How can I show in the form the current project instead of "------"?
You should not ground the ProjectForm in case you render the form with a GET requuest:
from django.shortcuts import get_object_or_404
def change_project(request, user):
profile = get_object_or_404(Profile, user__username=user)
if request.method == 'POST':
form = ProjectForm(request.POST, instance=profile)
if form.is_valid():
form.save()
else:
form = ProjectForm(instance=profile)
return render(request, 'datafiller/change_project.html', {'form': form})
I am using the same form for profile_edit and create_profile functionality. It is updating the multi-choice values in the profile_edit page but does not create in create_profile.
Below is the form code in forms.py
class ProfileForm(ModelForm):
full_name = forms.CharField(required=True)
current_position = forms.CharField(required=True)
about_me = forms.Textarea(attrs={'required':True})
topic_name = forms.ModelMultipleChoiceField(Topic.objects.all())
class Meta:
model = Profile
fields =(
"full_name",
"current_position",
"about_me",
"topic_name",
)
Below is the views.py for profile creation
def create_profile(request, user_id):
if request.method == "POST":
form = ProfileForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
user = get_object_or_404(User, id=user_id)
form.user = user
print(form.topic_name.all()) # Prints empty queryset
form.save()
return redirect("profile_view", user_id=user_id)
else:
context = {"form": form}
return render(request, "profile/create_profile.html", context)
else:
form = ProfileForm()
context = {
"form": form
}
return render(request, "profile/create_profile.html", context)
Below is Model.py
class Topic(models.Model):
topic = models.CharField(max_length=12)
def __str__(self):
return self.topic
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True,)
full_name = models.CharField(max_length=60, null=True)
current_position = models.CharField(max_length=64, null=True)
about_me = models.TextField(max_length=255, null=True)
topic_name = models.ManyToManyField(Topic)
def __str__(self):
return self.full_name
Both create_profile and edit_profile templates are exactly the same.
It saves everything except Multichoice field.
When you do save(commit=False),
you need to use mymodelform.save_m2m() below save(commit=True) on your ModelForm,
because many to many relationships cannot be saved without an ID.
see this docs
so in your views.py
if form.is_valid():
profile = form.save(commit=False)
user = get_object_or_404(User, id=user_id)
profile.user = user
profile.save()
form.save_m2m()
return redirect("profile_view", user_id=user_id)
I'm trying to do a form so a user can upload a video, the problem is i can't get current user or it's id as a foreign key on my video model
Error: IntegrityError
Exception Value: (1048, "Column 'owner_id' cannot be null")
How can i solve the problem please, i looked at django documentation but doesn't find answer.
My models.py:
class Videowtm(models.Model):
name = models.CharField(max_length=50, blank=True)
description = models.CharField(max_length=255, blank=True)
uploaded_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User)
video = models.FileField(upload_to='videos/')
My forms.py:
class VideowtmForm(forms.ModelForm):
class Meta:
model = Videowtm
fields = ('name', 'description', 'video', )
My views:
#login_required
def model_form_upload(request):
if request.method == 'POST':
form = VideowtmForm(request.POST, request.FILES)
form.owner = request.user
if form.is_valid():
form.save()
return redirect('home')
else:
form = VideowtmForm()
return render(request, 'model_form_upload.html', {
'form': form
})
Try this one:
first add blank=True to the owner in your model:
###No need for this if you don't include it in your form fields###
class Videowtm(models.Model):
name = models.CharField(max_length=50, blank=True)
description = models.CharField(max_length=255, blank=True)
uploaded_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, blank=True)
video = models.FileField(upload_to='videos/')
and then:
views.py:
#login_required
def model_form_upload(request):
if request.method == 'POST':
form = VideowtmForm(request.POST, request.FILES)
if form.is_valid():
video = form.save(commit=False)
video.owner = request.user
video.save()
return redirect('home')
else:
form = VideowtmForm()
return render(request, 'model_form_upload.html', {
'form': form
})
In my Django project i create an app to have additional information about registered users. So my model looks like this:
class UserProfile(models.Model):
class Meta:
verbose_name_plural = u'User Profile'
user = models.OneToOneField(User)
birthday = models.DateField(blank=True, null=True)
avatar = models.ImageField(upload_to='media/profile/avatar', blank=True, null=True)
name = models.CharField(blank=True, null=True, max_length=20)
surname = models.CharField(blank=True, null=True, max_length=50)
phone = models.CharField(blank=True, null=True, max_length=12)
def __unicode__(self):
return '%s' % self.user
In user profile i create modelform where user can fill or edit the fields from UserProfile model:
class ExtraProfileDataForm(ModelForm):
name = forms.CharField(label=(u'Enter your name'))
surname = forms.CharField(label=(u'Enter your surname'))
phone = forms.CharField(label=(u'Enter your phone'))
birthday = forms.DateField(label=(u'Enter birthday'))
avatar = forms.ImageField(label=(u'Enter avatar'))
class Meta:
model = UserProfile
fields = ('name', 'surname', 'phone', 'birthday', 'avatar')
def __init__(self, *args, **kwargs):
super(ExtraProfileDataForm, self).__init__(*args, **kwargs)
for key in self.fields:
self.fields[key].required = False
This is the view of the model form:
#login_required
def UserFullDataForm(request):
if request.method == 'POST':
form = ExtraProfileDataForm(request.POST)
if form.is_valid():
profile_user = request.user
user_profile = UserProfile(user=profile_user)
user_profile.name = form.cleaned_data['name']
user_profile.surname = form.cleaned_data['surname']
user_profile.phone = form.cleaned_data['phone']
user_profile.birthday = form.cleaned_data['birthday']
user_profile.avatar = form.cleaned_data['avatar']
user_profile.save()
return HttpResponseRedirect('/profile/')
else:
return render(request, 'profiles/extra_profile.html', {'form':form})
else:
form = ExtraProfileDataForm()
context = {'form':form}
return render (request, 'profiles/extra_profile.html', context)
But i want to load on ExtraProfileDataForm initial data from model UserProfile if the fields not empty. I searched how to do that on Django documentation website, but nothing found. Can somebody help me to understand how to do it? Thanks a lot.
You use the instance parameter.
Note that you are doing much more work than necessary here; most of your view can be cut.
#login_required
def UserFullDataForm(request):
try:
profile = request.user.userprofile
except UserProfile.DoesNotExist:
profile = UserProfile(user=request.user)
if request.method == 'POST':
form = ExtraProfileDataForm(request.POST, instance=profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/profile/')
else:
form = ExtraProfileDataForm(instance=profile)
return render(request, 'profiles/extra_profile.html', {'form':form})
Similarly, in your form, you don't need the overridden __init__ method because you're manually specifying all the fields anyway; you can add required=False on each one there. However, you could make this even shorter by adding the labels in the model definition; then your entire modelform could just be:
class ExtraProfileDataForm(ModelForm):
class Meta:
model = UserProfile
fields = ('name', 'surname', 'phone', 'birthday', 'avatar')
One final note: you're consistently using three-space indentation, which is a bit, well, odd. Most Python programmers prefer two or four.