It sound simple but I want my page to display the database of my model.
I use ModelForm for user to input and it would save into my model. Now I want to render the whole table, not just each separately.
forms.py
class My_Folio(forms.ModelForm):
class Meta:
model = my_data
fields = ['symbol','buy_price','quantity']
views.py
def blockfolio(request):
if request.method == 'POST':
my_folio = My_Folio(request.POST)
if my_folio.is_valid():
symbol = my_folio.cleaned_data['symbol']
buy_price = my_folio.cleaned_data['buy_price']
quantity = my_folio.cleaned_data['quantity']
instance = my_folio.save(commit=False)
instance.save()
return render(request, 'blockfolio/blockfolio.html', {'symbol':symbol, 'buy_price':buy_price, 'quantity':quantity, 'instance':instance})
template:
{{instance}} This give me the user input after submit, but I want to show all of the inputs saved in database.
Maybe your post is invalid. Try this code in views.py.
def blockfolio(request):
if request.method == 'POST':
my_folio = My_Folio(request.POST)
if my_folio.is_valid():
symbol = my_folio.cleaned_data['symbol']
buy_price = my_folio.cleaned_data['buy_price']
quantity = my_folio.cleaned_data['quantity']
instance = my_folio.save(commit=False)
instance.save()
return render(request, 'blockfolio/blockfolio.html', {'symbol':symbol, 'buy_price':buy_price, 'quantity':quantity, 'instance':instance})
else:
print("request is invalid: {}".format(request.POST))
return "bad request!", 500
Related
I am trying to create an endpoint to edit both the user model and custom profile model below.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500)
location = models.CharField(max_length=50)
image = models.ImageField(default='default.jpg', upload_to='profile')
In the regular django I would do:
views.py
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
extended_profile_form = ProfileForm(request.POST,
request.FILES,
instance=request.user.profile)
if form.is_valid() and extended_profile_form.is_valid():
form.save()
extended_profile_form.save()
return redirect('accounts:profile')
else:
form = EditProfileForm(instance=request.user)
extended_profile_form = ProfileForm(instance=request.user.profile)
context = {
'form':form,
'extended_profile_form':extended_profile_form
}
return render(request, 'accounts/edit-profile.html', context)
what is the equivalent for django rest framework?
I have tried:
views.py (Django Rest Framework)
#api_view(['GET','PUT'])
def profile(request):
if request.method == 'GET':
user = User.objects.filter(username=request.user)
profile_user = Profile.objects.filter(user=request.user)
serializer_user = UserSerializer(user, many=True)
serializer_profile_user = ProfileSerializer(profile_user, many=True)
result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
return Response(result)
elif request.method == 'PUT':
user = User.objects.filter(username=request.user)
profile_user = Profile.objects.filter(user=request.user)
serializer_user = UserSerializer(user, data=request.data)
serializer_profile_user = ProfileSerializer(profile_user, data=request.data)
if serializer_user.is_valid() and serializer_profile_user.is_valid():
serializer_user.save()
serializer_profile_user.save()
result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
return Response(result)
result = {'serializer_user': serializer_user.data, 'serializer_profile_user': serializer_profile_user.data}
return Response(result.errors, status=status.HTTP_400_BAD_REQUEST)
When I am browsing the endpoint, it does display serializer_user and serializer_profile_user data but I am unable to edit any of those data using the DRF browsable API.
Am I right thinking the codes above is the equivalent of the codes from the codes from the normal django to edit the profile of the user?
It looks fine to me, but you need to replace this:
if request.method == 'GET':
user = User.objects.filter(username=request.user)
with this:
if request.method == 'GET':
try:
user = User.objects.get(id=request.user.id)
except User.DoesNotExist:
return Response(data='no such user!', status=status.HTTP_400_BAD_REQUEST)
# you need to use objects.get because objects.filter returns a queryset not an abject
Because, request.user is an instance of User model, you cannot compare it to an attribute of user (in your case username)
PS: same goes with your PUT method as well.
Hope this helps!
Look. You can make it easier. Let's take Post model (for example):
class Post(models.Model):
author = models.ForeignKey(base.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
text = models.TextField()
likes = models.ManyToManyField(base.AUTH_USER_MODEL, blank=True, related_name='post_likes')
created_date = models.DateTimeField(default=timezone.now)
And that You should describe it in your serializer (serializer is something similar to DTO. It converts data into a service-friendly JSON view):
class PostCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'text']
And the last part - Endpoint:
class PostUpdateView(UpdateAPIView):
serializer_class = PostCreateUpdateSerializer
def get_queryset(self):
return Post.objects.filter(author=self.request.user)
It will be more comfortable to use CBV for Django and DRF
And One more thing. You shouldn't create one more table for your user model. This is due to the extension of the BaseUser model. Link for help
I can create model objects through admin panel. But I want it to be created on website. The code below allows me to enter values of a model, and when I submit it, it redirects to the written url, which happens after form.save. This is the message from server "POST /taskcreate HTTP/1.1" 302 0. But there is no changes in database. How to solve this issue? Any thoughts... Thanks
models.py
class Task(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
pub_date = models.DateTimeField('date_published', auto_now_add = True)
cost = models.IntegerField()
def __str__(self):
return '%s' % (self.name)
forms.py
class TaskCreateForm(forms.ModelForm):
class Meta:
model = Task
fields = ('name', 'description', 'cost')
views.py
def TaskCreateView(request):
if request.method == 'POST':
form = TaskCreateForm(request.POST)
if form.is_valid():
form.save
return redirect('home')
else:
form = TaskCreateForm()
return render(request, 'employer/create_task.html')
You didn't actually call the save method.
if form.is_valid():
form.save()
return redirect('home')
When you use ModelForm you just need to write form.save() method right after if is_valid() if case. In your case, you are missing curly brackets after save.
def TaskCreateView(request):
if request.method == 'POST':
form = TaskCreateForm(request.POST)
if form.is_valid():
form.save() # here you were missing curly brackets
return redirect('home')
else:
form = TaskCreateForm()
return render(request, 'employer/create_task.html')
I'm doing a multi step form where everything is saved at the end. In my models I have a m2m checkbox field and I'm using django Sessions to grab the forms datas to show it on the final step.
The issue is that the m2m field (checkboxes) is not saved when I submit the final form.
Here is my views file :
views.py
def step1(request):
initial={'name': request.session.get('name', None), 'checkbox': request.session.get('checkbox', (False,))} #cookies
form = FormOneForm(request.POST or None, initial=initial)
if request.method == 'POST':
if form.is_valid():
request.session['name'] = form.cleaned_data['name']
request.session['checkbox'] = form.cleaned_data.get('checkbox')
return HttpResponseRedirect(reverse('step2'))
return render(request, 'step1.html', {'form': form})
def step2(request):
form = FormTwoForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
formtwo = form.save(commit=False)
formone2 = FormOne.objects.create(checkbox=request.session.get('checkbox')) #error is here
formone = FormOne.objects.create(name=request.session['name'])
formtwo.owner = formone
formtwo.save()
formone2.save_m2m()
return HttpResponseRedirect(reverse('step3'))
return render(request, 'step2.html', {'form': form})
models.py
class Font(models.Model):
font_name = models.CharField(max_length=100)
font_family = models.CharField(max_length=100)
font_link = models.CharField(max_length=100)
...
class FormOne(models.Model):
name = models.CharField(max_length=40)
checkbox = models.ManyToManyField(Font, blank=True)
...
class FormTwo(models.Model):
owner = models.ForeignKey(FormOne)
name = models.CharField(max_length=40)
...
this code gives me this error :
'checkbox' is an invalid keyword argument for this function
How can I achieve what I am trying to realise ?
Try to save object first:
formone2 = FormOne.objects.create(name=request.session['name'])
formone2.checkbox.add(request.session.get('checkbox')
The problem is that you need to save object before use Many-to-many relations. See docs:
You can’t associate it with a Publication until it’s been saved
Lets say I have an incident loaded into the database, where there is information in the description and status fields, but action_taken is left NULL.
class Incident(models.Model):
description = models.TextField()
status = models.ForeignKey(Status, default="open")
action_taken = models.TextField()
How can I load information into the action_taken field using this form and view?
forms.py
class ResolveForm(forms.Form):
action_taken = forms.CharField(widget=forms.Textarea)
views.py
def detail(request, incident_id):
incident = get_object_or_404(Incident, pk=incident_id)
template = "incidents/detail.html"
if request.method == 'POST':
form = ResolveForm(request.POST or None)
if form.is_valid():
action_taken = (form.cleaned_data['action_taken'])
######### MY EFFORTS #########################
q = Incident(action_taken=action_taken)
q.save()
print(incident.id)
#new_incident, created = Incident.objects.get_or_create(action_taken)
##############################################
return render(request, template, {'form': form})
else:
form = ResolveForm()
context = { 'incident': incident,
'form': form}
return render(request, template, context)
errors
incident.action_taken = action_taken
error: name 'action_taken' is not defined
How can I load information into the action_taken field using this form and view?
I see you already have your model instance incident, so this should do it
incident = get_object_or_404(Incident, pk=incident_id)
incident.action_taken = action_taken
incident.save()
If in your update you don't want to touch the other fields:
incident = get_object_or_404(Incident, pk=incident_id)
incident.action_taken = action_taken
incident.save(update_fields=['action_taken'])
To critique what you tried:
q = Incident(action_taken=action_taken)
q.save()
This doesn't get the object you want to update, but instead it creates a new one and saves it (not what you want)
I have an inlineformset based off a very simple Model form. I'd like a way to add a choiceset to one of the fields of the form, but I want to do it from the views.py file as the choiceset is generated dynamically. Is this possible? Python2.7, Django1.5
models.py
class RoleForm(ModelForm):
class Meta:
model = Role
fields = ['role_type', 'user', 'item']
views.py
def new(request):
''' Create a new application '''
user = request.user
associatedRoleTypes = getAssociatedRoleTypes(Application)
#^^^this returns a queryset, and is what I want model_choices to be equal to
RoleFormSetFactory = inlineformset_factory(Application, Role, can_delete=False, form=RoleForm)
if request.method == 'POST':
applicationForm = ApplicationForm(request.POST)
if applicationForm.is_valid():
new_application = applicationForm.save()
roleInlineFormSet = RoleFormSetFactory(request.POST, instance = new_application)
if roleInlineFormSet.is_valid():
roleInlineFormSet.save()
else:
print roleInlineFormSet.errors
return redirect(reverse('index'))
else:
applicationForm = ApplicationForm()
roleInlineFormSet = RoleFormSetFactory()
return render(request, 'who/editapp.html',
{'roleInlineFormSet': roleInlineFormSet,
'applicationForm': applicationForm
})