this me again. I have some trouble with my code. I made a form from ModelForm which have a model with 8 attributes, but i want to user fill only one of them,and one from the system. The one that user fill is okay, but the one filled with system is not working.
models.py
class SeminarProposal(md.Model):
# diisi oleh mahasiswa
fileProposal = models.FileField()
# This is the one is filled with system
proposal = models.OneToOneField(Proposal,
on_delete=models.CASCADE,
related_name="propSid",
unique=True, blank=True, null=True)
masabimbingan = models.BooleanField(default=True)
# disi oleh admin
tanggal = models.DateField(default=timezone.now, blank=True,null=True)
tempat = models.CharField(max_length=30, blank=True, null=True)
# diisi oleh dosen pembimbing
dospemsetuju = models.BooleanField(default=False, blank=True)
# diisi oleh kaprodi
penguji1 = models.ForeignKey(Dosen,
on_delete=models.CASCADE,
related_name="penguji1",
blank=True, null=True)
penguji2 = models.ForeignKey(Dosen,
on_delete=models.CASCADE,
related_name="penguji2",
blank=True, null=True)
def __str__(self):
return "Sidang untuk " + self.proposal.judul
view.py
def daftarSeminar(request):
if request.method == 'POST':
form = FormSeminar(request.POST, request.FILES)
print(request.user)
if form.is_valid():
form.save(commit=False)
form.cleaned_data['proposal']
print(request.user)
prop = Proposal.objects.get(akun=request.user)
form.proposal = prop
print(form.proposal) #to confirm that this is not None
form.save()
return redirect('proposal:bimbingan')
else:
return render(request, 'sidprop.html' , {'oke': 'oke'})
return redirect('proposal:index')
form.py
class FormSeminar(forms.ModelForm):
class Meta:
model = SeminarProposal
fields = ['fileProposal','proposal']
Thanks in advance. Terimakasih.
Instead of changing the form data, get the object from form and change the object's data:
if form.is_valid():
obj = form.save(commit=False)
prop = Proposal.objects.get(akun=request.user)
obj.proposal = prop
obj.save()
return redirect('proposal:bimbingan')
Related
I'm currently processing a payment thing for an online subscription service and in order to get the users info to send this stuff, I have a payment form.
But, for some reason the payment form is not saving to the users account. Everything else actually processes and the only error I can trigger is a 'NOT NULL constraint failed: memberships_usermembership.user_id'
Here's what I have in my view -
#login_required()
def payments(request):
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
form = SubscriptionForm()
if request.method == "POST":
form_data = {
'full_name': request.POST['full_name'],
'email': request.POST['email'],
'phone_number': request.POST['phone_number'],
'country': request.POST['country'],
'postcode': request.POST['postcode'],
'town_or_city': request.POST['town_or_city'],
'street_address1': request.POST['street_address1'],
'street_address2': request.POST['street_address2'],
'county': request.POST['county'],
}
token = request.POST['stripeToken']
form = SubscriptionForm(form_data)
if form.is_valid():
customer = stripe.Customer.retrieve(
user_membership.stripe_customer_id)
customer.source = token
customer.save()
subscription = stripe.Subscription.create(
customer=user_membership.stripe_customer_id,
items=[
{"plan": selected_membership.stripe_plan_id},
]
)
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
user_membership.membership = selected_membership
user_membership.save()
form.save(commit=True)
subscription_id = subscription.id
sub, created = Subscription.objects.get_or_create(
user_membership=user_membership)
sub.stripe_subscription_id = subscription_id
sub.active = True
sub.save()
try:
del request.session['selected_membership_type']
except BaseException:
pass
return render(request, 'memberships/update-success.html')
else:
return redirect(reverse('membership_list'))
context = {
'selected_membership': selected_membership,
'form': form,
}
return render(request, 'memberships/payment.html', context)
When the form.save() is the line above the return(render) line, it will process everything as normal, and the form information just wont save into the DB.
It flashes the NOT NULL error when the form.save() line is where it in in the code above.
Any ideas how to get this working?
Thanks!
EDIT: Here's a link to the entire error in Django - http://dpaste.com/140VD8M
& a screenshot of it too!
Here's my models -
class Membership(models.Model):
membership_type = models.CharField(
choices=MEMBERSHIP_CHOICES,
default='Free',
max_length=30)
price = models.IntegerField(default=15)
description = models.TextField(default="DESCRIPTION")
image_url = models.URLField(max_length=1024, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
stripe_plan_id = models.CharField(max_length=40)
def __str__(self):
return self.membership_type
class UserMembership(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
full_name = models.CharField(max_length=50, null=True, blank=True)
email = models.EmailField(max_length=254, null=True, blank=True)
phone_number = models.CharField(max_length=20, null=True, blank=True)
country = CountryField(blank_label='Country', default="Ireland")
postcode = models.CharField(max_length=20, null=True, blank=True)
town_or_city = models.CharField(max_length=40, null=True, blank=True)
street_address1 = models.CharField(max_length=80, null=True, blank=True)
street_address2 = models.CharField(max_length=80, null=True, blank=True)
county = models.CharField(max_length=80, null=True, blank=True)
stripe_customer_id = models.CharField(max_length=40)
membership = models.ForeignKey(
Membership, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.user.username
def post_save_usermembership_create(
sender, instance, created, *args, **kwargs):
user_membership, created = UserMembership.objects.get_or_create(
user=instance)
if user_membership.stripe_customer_id is None or user_membership.stripe_customer_id == '':
new_customer_id = stripe.Customer.create(email=instance.email)
free_membership = Membership.objects.get(membership_type='Free')
user_membership.stripe_customer_id = new_customer_id['id']
user_membership.membership = free_membership
user_membership.save()
post_save.connect(post_save_usermembership_create,
sender=settings.AUTH_USER_MODEL)
class Subscription(models.Model):
user_membership = models.ForeignKey(
UserMembership, on_delete=models.CASCADE)
stripe_subscription_id = models.CharField(max_length=40)
active = models.BooleanField(default=False)
def __str__(self):
return self.user_membership.user.username
& here's my user membership def -
#login_required()
def get_user_membership(request):
user_membership_qs = UserMembership.objects.filter(user=request.user)
if user_membership_qs.exists():
return user_membership_qs.first()
return None
Instead of collecting all the form fields individually, you should be able to just pass the request.POST to the form like so:
form_data = request.POST
token = request.POST['stripeToken']
form = SubscriptionForm(form_data)
Other than that, without seeing the exact error message, there isn't much more to tell. If you update your question I will update my answer.
EDIT:
Without seeing your model and what get_user_membership() returns, it looks like you are missing a User object in a UserMembership class (but I can't tell without seeing more):
user_membership.user = request.user
Or something like that.
i want to save an object to db and it worked one time but now it doesnt, i suspect that is something to do with the Glossary
Everything
views.py
#login_required
def product_form_view(request):
if request.method == 'POST':
form = Product_Form(request.POST, request.FILES)
if form.is_valid():
product_form = form.save()
product_form.save()
return redirect('product_management_view')
else:
form = Product_Form()
return render(request, 'product-form.html', {'form': form})
models.py
class Product (models.Model):
sub_chapter = models.ForeignKey(Sub_Chapter, on_delete=models.CASCADE)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
glossary = models.ManyToManyField(Glossary, blank=True )
name = models.CharField(max_length=40, blank=False, null=False)
description = models.TextField(null=True)
product_image = models.ImageField(
upload_to='media/images/product_images', blank=False, null=False)
reference = models.CharField(max_length=40, blank=False, null=False)
width = models.PositiveIntegerField()
height = models.PositiveIntegerField()
length = models.PositiveIntegerField()
unit_price = models.DecimalField(
max_digits=15, decimal_places=4, null=True)
polution = models.DecimalField(decimal_places=8, max_digits=15, null=True, blank=True )
technical_implementation = models.TextField(null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse_lazy("manufacter_product_view", kwargs={'id': self.pk})
forms.py
class Product_Form(forms.ModelForm):
sub_chapter = forms.ModelChoiceField(queryset=Sub_Chapter.objects.all(),
required=True, widget=forms.Select())
supplier = forms.ModelChoiceField(queryset=Supplier.objects.all(),
required=True, widget=forms.Select())
glossary = forms.ModelChoiceField(queryset=Glossary.objects.all(),
required=False, widget=forms.SelectMultiple())
product_image = forms.ImageField(
required=True, widget=forms.FileInput())
class Meta():
model = Product
fields =[ 'name', 'description', 'reference', 'width', 'height', 'length', 'polution', 'unit_price', 'technical_implementation', 'sub_chapter', 'supplier', 'glossary', 'product_image', ]
There is a bug in your product_form_view, you are calling the save method on product_form variable i.e product_form.save() but product_form will have None in it as form.save() will return None on successfully saving the object,so it will break the code there.And you don't need to again call the save method at all.Calling form.save() is enough for saving the object and you should move the code in else part out of it as it not currently handling the form invalid case.
Your code should be like this:
#login_required
def product_form_view(request):
if request.method == 'POST':
form = Product_Form(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('product_management_view')
form = Product_Form()
return render(request, 'product-form.html', {'form': form})
I have two models: Properties and Bedroom, which are connected through a foreign key "Property" on the Bedroom model.
#models.py
class Property(models.Model):
property_reference = models.CharField(db_column='Property_Reference', max_length=10, unique=True) # Field name made lowercase.
address = models.CharField(db_column='Address', max_length=250, blank=True, null=True) # Field name made lowercase.
post_code = models.CharField(db_column='Post_Code', max_length=15, blank=True, null=True) # Field name made lowercase.
type = models.CharField(db_column='Type', max_length=25, blank=True, null=True, choices=HOUSE_TYPE_CHOICES) # Field name made lowercase.
bedrooms = models.IntegerField(db_column='Bedrooms', blank=True, null=True) # Field name made lowercase.
bathrooms = models.IntegerField(db_column='Bathrooms', blank=True, null=True) # Field name made lowercase.
usual_cleaning_requirements = models.CharField(db_column='Usual_Cleaning_Requirements', max_length=250, blank=True, null=True) # Field name made lowercase.
notes = models.CharField(db_column='Notes', max_length=500, blank=True, null=True) # Field name made lowercase.
feature_image = models.ImageField(upload_to='properties',null=True)
class Meta:
db_table = 'Property'
def __str__(self):
return self.property_reference
def get_absolute_url(self):
return reverse("properties:property_detail",kwargs={'pk':self.pk})
class Bedroom(models.Model):
type = models.CharField(db_column='Type', choices=BEDROOM_TYPE_CHOICES, max_length=50)
bed_dimensions = models.CharField(db_column='Bed_Dimension', choices=BED_DIMENSION_CHOICES, max_length=30)
image = models.ImageField(null=True, blank=True)
ensuite = models.BooleanField(default=False)
notes = models.CharField(db_column='Notes', max_length=500, blank=True, null=True) # Field name made lowercase.
property = models.ForeignKey(Property, null=False, on_delete=models.CASCADE, related_name='bedroom')
I have a Property DetailView Class that shows all the details on my template at "property-detail.html". Also on my template I have a button like this:
<a class="btn btn-secondary float-right" href="{% url 'properties:add_bedroom' pk=object.pk %}"><i class="fas fa-plus-circle"></i> Add New</a>
This button takes me to the right place, to the form AddBedroom with this link:
http://127.0.0.1:8000/properties/1/bedrooms/add-bedroom/
My urls.py look like this:
url(r'^(?P<pk>\d+)$',views.PropertyDetailView.as_view(),name='property_detail'),
url(r'^(?P<pk>\d+)/edit$',views.PropertyUpdateView.as_view(),name='property_edit'),
url(r'^(?P<pk>\d+)/bedrooms/add-bedroom/',views.add_bedroom,name='add_bedroom'),
You can see here how I render the form:
#views.py
def add_bedroom(request, pk):
print(pk)
if request.method == 'POST':
form = AddBedroomForm(request.POST, request.FILES)
if form.is_valid():
add_bedroom = form.save()
add_bedroom.instance.property = Property.objects.get(pk = pk)
print('Sucesso')
add_bedroom.save()
return HttpResponseRedirect('/thanks/')
else:
print('Error')
form = AddBedroomForm()
context = {
'add_bedroom_form':form,
'title':"Add Bedroom",
}
return render(request, 'properties/add-bedroom.html', context)
I can get the "PK" printed, I also get the POST on console but it just refreshes the page and does not actually POSTS anything. I'm sure I'm doing something wrong because I'm fairly new to Django.
I've came up with a solution, I don't know if it's the best practice but it's working fine.
I've changed the views.py to this:
#views.py
def add_bedroom(request, pk):
get_property_id = pk
data = {'property':get_property_id}
property_reference = Property.objects.get(pk=get_property_id)
print(property_reference)
if request.method == 'POST':
form = AddBedroomForm(request.POST, request.FILES, initial=data)
print(get_property_id)
if form.is_valid():
add_bedroom = form.save()
add_bedroom.save()
return HttpResponseRedirect('/thanks/')
else:
print('Error')
form = AddBedroomForm(initial=data)
context = {
'add_bedroom_form':form,
'title':"Add Bedroom",
'reference':property_reference,
}
return render(request, 'properties/add-bedroom.html', context)
What am I doing wrong?
I have two tables, User and Entrepreneur. Objects are not saving in the Entrepreneur table. I even used the shell!
I've deleted the DB and migration files and the error stays the same.
I know similar questions have been asked but I found none fitting my situation.
MY MODELS:
class EntrepreneurProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile = models.CharField(max_length=100, blank=True, null=True)
location = CountryField(blank=True, null=True)
email_notif_on = models.BooleanField(default=False)
photo = models.ImageField(upload_to='photo/%Y/%m/%d', blank=True, null=True)
skills = TaggableManager(blank=True)
date_joined = models.DateField(auto_now_add=True)
accomplishnment = models.ForeignKey(Accomplishment, on_delete=models.CASCADE, null=True, blank=True)
portfolio = models.ManyToManyField(Portfolio, blank=True)
date_of_birth = models.DateField(blank=True, null=True)
url = models.SlugField(unique=True)
def __str__(self):
return f'{self.user}'
def save(self, *args, **kwargs):
if self.url:
self.url = slugify(f'{self.user.first_name} {self.user.last_name} {str(uuid.uuid4()[:7])}')
MY VIEWS:
def signup(request):
if request.method == 'POST':
user_form = UserCreateForm(request.POST)
if user_form.is_valid():
user = user_form.save(commit=False)
user.set_password(user.password)
user.save()
entrep = EntrepreneurProfile.objects.create(user=user)
entrep.save()
print(entrep.id)
return redirect('users:login')
else:
user_form = UserCreateForm()
data = {'user_form': user_form}
return render(request, 'users/signup.html', data)
It seems you forgot to call super().save(*args, **kwargs) in your save method as it is mentioned in
https://docs.djangoproject.com/en/2.2/topics/db/models/#overriding-predefined-model-methods
Let's get to the problem
I have a page where I want users to fill info about themselves, and i would like to save that data. But I'm getting this error.
IntegrityError at /accounts/profile/edit/1/change-profile/
UNIQUE constraint failed: accounts_user.username
this is my view.py
def change_profile(request, pk):
form = ChangeProfile(request.POST or None)
user_ = request.user
if request.method == "POST":
if form.is_valid():
form.save()
return redirect("/accounts/profile/edit/{}/".format(user_.pk))
args = {'form': form}
return render(request, 'change_profile.html', args)
my models.py
class GradeUser(models.Model):
grade = models.CharField(max_length=20, null=True)
class Country(models.Model):
country = models.CharField(max_length=30, null=True)
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name = 'email address',
max_length=255,
unique=True
)
real_name = models.CharField(max_length=20, blank=True)
username = models.CharField(max_length=40, unique=True, verbose_name='username')
grade = models.ForeignKey(GradeUser, on_delete=models.CASCADE, blank=True, null=True)
country = models.ForeignKey(Country, on_delete=models.CASCADE, blank=True, null=True)
reputation = models.IntegerField(default=0)
image = models.ImageField(upload_to='accounts/media', blank=True)
about_me = models.TextField()
USERNAME_FIELD= 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
forms.py
class ChangeProfile(forms.ModelForm):
class Meta:
model = User
fields = ('real_name', 'grade', 'country', 'about_me')
What does exactly go wrong?
Why would it need a user's username?
What should I do with it to save?
You aim to perform an update on your User (that already exists) but here you are creating a whole new user instance with no username attribute and that's what generates the error.
Try this code : it gets your current user and updates it with the info provided from the form.
PS : I did not modify anything about the returns because I dunno what you're doing there but note that you don't need to pass the user pk through the arguments, the user data is already stored in the request object.
def change_profile(request, pk):
form = ChangeProfile()
user_ = request.user
if request.method == "POST":
form = ChangeProfile(request.POST)
if form.is_valid():
user_new_info=form.save(commit=false)
user_.real_name = user_new_info.real_name
user_.grade = user_new_info.grade
user_.country = user_new_info.country
user_.about_me = user_new_info.about_me
user_.save()
return redirect("/accounts/profile/edit/{}/".format(user_.pk))
args = {'form': form}
return render(request, 'change_profile.html', args)