Django modelformset form is not blank when I return - django-models

If the database is empty and I go to my form it looks the way it is supposed to. There is two spots for parent information and two spots for child information. If I fill the form out and submit it I get no errors and I get taken to the thank you page. When I go back to the page with the form there are now four spots for parent information and four spots for child information. Two of the spots for child and parent information are filled out with the data that is now in the database. If you fill in the blank fields new data will get added to the database but if you change any information in the already populated fields it will change the information of the data already in the database. I have even tried manually inputing the data through the admin portal but when I go to the form the information I put in still shows up. It's like the formset is pulling information out of the database. How do I get this form so that when I go back to it after submitting data the form is blank again?
Form after data submission part 1
Form after data submission part 2
models.py
from django.db import models
class Child(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
birthday = models.DateField()
allergies = models.CharField(max_length=30)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Parent(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
child = models.ManyToManyField(Child)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Household(models.Model):
household_name = models.CharField(max_length=30)
parent = models.ManyToManyField(Parent)
def __str__(self):
return self.household_name
forms.py
from django import forms
from .models import Child, Household, Parent
class HouseholdForm(forms.ModelForm):
class Meta:
model = Household
fields = ('household_name',)
class ParentForm(forms.ModelForm):
class Meta:
model = Parent
fields = ('first_name', 'last_name',)
class ChildForm(forms.ModelForm):
class Meta:
model = Child
fields = ('first_name', 'last_name', 'birthday', 'allergies',)
views.py
from django.forms import modelformset_factory
from django.shortcuts import get_object_or_404, render, redirect
from .forms import ChildForm, HouseholdForm, ParentForm
from .models import Child, Parent, Household
def register(request):
ParentFormSet = modelformset_factory(Parent, form=ParentForm, extra=2)
ChildFormSet = modelformset_factory(Child, form=ChildForm, extra=2)
if request.method == "POST":
formset1 = ParentFormSet(request.POST, prefix="parent",)
formset2 = ChildFormSet(request.POST, prefix="child",)
if formset1.is_valid() and formset2.is_valid():
formset1.save()
formset2.save()
return redirect('thanks',)
else:
formset1 = ParentFormSet(prefix="parent",)
formset2 = ChildFormSet(prefix="child",)
return render(request, 'register.html', {'formset1': formset1, 'formset2': formset2,})
def thanks(request):
return render(request, 'thanks.html')

Related

How to Implement One to Many in DRF

I am Designing a Model
class Timer(models.Model):
total_time = models.FloatField(default=5)
date_time = models.DateTimeField(auto_now_add=True)
class WatchTiming(models.Model):
user = models.OneToOneField("authentication.User", on_delete=models.CASCADE, primary_key=True)
current_timer = models.ForeignKey(Timer, on_delete=models.CASCADE, related_name="current_timer")
previous_timers = models.ForeignKey(Timer, on_delete=models.CASCADE, related_name="previous_timers")
and serializer for this model is
from rest_framework import serializers
from .models import Timer, WatchTiming
class TimerSerializer(serializers.ModelSerializer):
class Meta:
model = Timer
exclude = ("id",)
class WatchTimingSerializer(serializers.ModelSerializer):
current_timer = TimerSerializer(required=False)
previous_timers = TimerSerializer(many=True, read_only=True)
user = serializers.PrimaryKeyRelatedField(read_only=True)
class Meta:
model = WatchTiming
fields = "__all__"
def create(self, validated_data):
watch_timing = WatchTiming.objects.create(user=self.context["request"].user, current_timer=Timer.objects.create())
return watch_timing
WatchTiming is a table that is used to store user watch time
current_timer stores today's timer
when the day expires current_timer values are added in the previous_timer and the current_timer value is replaced with the default
Now My issue is how can I create one to many relationships, I already have written relationships but its not working
I have been stuck on this for 4 consecutive days.
You can use a subserializer, just like you did with your TimerSerializers:
from rest_framework import serializers
from .models import Timer, WatchTiming
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User # authentication.User
fields = (
'id',
'username',
)
class WatchTimingSerializer(serializers.ModelSerializer):
current_timer = TimerSerializer(required=False)
previous_timers = TimerSerializer(read_only=True)
user = serializers.UserSerializer(read_only=True)
class Meta:
model = WatchTiming
fields = '__all__'
def create(self, validated_data):
return WatchTiming.objects.create(
user=self.context['request'].user,
current_timer=Timer.objects.create(),
)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: The related_name=… parameter [Django-doc]
is the name of the relation in reverse, so from the Timer model to the WatchTiming
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the current_timer relation to watch_timings.
By using SerializerMethodField you can create one to many relationships.
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__"
class WatchTimingSerializer(serializers.ModelSerializer):
current_timer = TimerSerializer(required=False)
previous_timers = TimerSerializer(many=True, read_only=True)
user = serializers.SerializerMethodField(read_only=True)
class Meta:
model = WatchTiming
fields = "__all__"
def get_user(self, obj):
data = User.objects.filter(id=obj.id)
return UserSerializer(data, many=True).data

How to retrieve and assign current user object to a field in Wagtail admin?

I have a few Django models that I display in the admin using wagtail’s modelAdmin. few of the fields in the models are referencing the user model. Since I’m not creating the form/page and it’s handled by wagtail, how do I pass the current user object to the field when it’s saved? That is, the created and updated by fields should have the current user object assigned to them.
See code snippet below, currently I'm assigning the user manually by querying, instead I'd like to get the current user.
from django.db import models
from django.conf import settings
from django.contrib.auth import get_user_model
from wagtail.admin.forms import WagtailAdminPageForm
STATUS_CHOICES = (
(1, 'Active'),
(2, 'Inactive')
)
class BasePageForm(WagtailAdminPageForm):
def save(self, commit=True):
auth_user_model = get_user_model()
default_user = auth_user_model.objects.get(username='admin')
page = super().save(commit=False)
if not page.pk:
page.created_by = default_user
page.updated_by = default_user
else:
page.updated_by = default_user
if commit:
page.save()
return page
class BaseModel(models.Model):
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='created%(app_label)s_%(class)s_related'
)
created_at = models.DateTimeField(auto_now_add=True)
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='updated%(app_label)s_%(class)s_related'
)
updated_at = models.DateTimeField(auto_now=True)
status = models.IntegerField(choices=STATUS_CHOICES, default=1)
class Meta:
abstract = True # Set this model as Abstract
base_form_class = BasePageForm

Django - save form into database

Hey guy I need your help
so I have this model:
class PreferedShops(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
shop = models.ForeignKey(Shops, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.user.username, self.shop.name
and this is the form:
class LikeShopForm(forms.ModelForm):
class Meta:
model = PreferedShops
fields = ['date_posted']
and this is the view:
def shops(request):
if request.method == 'POST':
form = LikeShopForm(request.POST)
if form.is_valid():
u = form.save(commit=False)
u.user = request.user
u.shop = request.shop
u.save()
return redirect('shops')
else:
form = LikeShopForm()
return render(request, "shops.html", {'form': form})
the probleme that I have is when I click on Like Button, I want that the form takes automatically the user and the name of the shop, and then save them into the DB
the user and the shop's name should be hidden
when I click submit I have this error 'WSGIRequest' object has no attribute 'shop'
please help me to take the shop's name automatically and save it in the db
Well the shop is not part of the request (strictly speaking, user is not either, but it is frequently added to the request object in the middelware by looking at the session).
You thus need to encode it into the URL, or in the POST parameters. For example with:
# app/urls.py
from django.urls import path
from app.views import like_shop
urlpatterns = [
path('shop/<int:shop_id>/like', like_shop, name='like_shop'),
]
Then in the view we obtain a parameter shop_id that contains the id of the related Shops object:
from django.shortcuts import get_object_or_404
from app.models import Shops
def like_shop(request, shop_id):
if request.method == 'POST':
shop = get_object_or_404(Shops, id=shop_id)
form = LikeShopForm(request.POST)
if form.is_valid():
u = form.save(commit=False)
u.user = request.user
u.shop = shop
u.save()
return redirect('shops')
else:
form = LikeShopForm()
return render(request, "shops.html", {'form': form, 'shop_id': shop_id})
Then the request in the POST should point to:
<!-- shops.html -->
<form action="{% url 'like_shop' shop_id=shop_id %}" method="post">
<!-- ... -->
</form>
The URL to this page then thus looks like /shops/123/like with 123 the id of the shop. If you thus want to pass the shop "implicitly", you need to encode it in the URL. Otherwise, you should make it a field of the form, such that the user can pick an option. Personally I find it very strange that you use date_posted as a form field, since typically this is an field that I would expect to be filled in with the timestamp when the user likes the shop.
Note: the name of the models is normally singular, so Shop instead of Shops.

Django ImageField Upload

I am trying to use Django ImageField to allow a user to upload a profile picture. However, after browsing for the image, when I attempt to update the profile, the picture upload changes from the file name to "No file selected" and I receive "This file is required" error.
If it helps, I was following along with this tutorial. I do understand that he uses two character fields, but I was attempting to change it to handle FileFields. From other questions such as this one on stack overflow, I know that the form requires a request.FILES as well.
Here is my Views.py.
#login_required
def user_profile(request):
if request.method == 'POST':
form = UserProfileForm(request.POST, request.FILES, instance=request.user.profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/loggedin')
else:
user = request.user
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('profile.html', args)
Additionally, I have these two lines in my settings.
AUTH_PROFILE_MODULE = 'userprofile.UserProfile'
MEDIA_ROOT = 'E:\Pictures\django_stuff'
Let me know if there is anything else that is required.
As requested by Erny
Forms.py
from django import forms
from models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('logo', 'description')
Models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
logo = models.ImageField(upload_to = 'photos')
description = models.TextField()
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

how to insert data into database using forms in Django

models.py
class Author(models.Model):
author_id = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
age=models.IntegerField()
class Meta:
db_table=u'Author'
def __unicode__(self):
return u"%d %s %s %s %d" % (self.pk, self.first_name, self.last_name, self.email,self.age)
class Book(models.Model):
book_id=models.AutoField(primary_key=True,unique=True)
book_name=models.CharField(max_length=30)
publisher_name=models.CharField(max_length=40)
author=models.ForeignKey(Author)
class Meta:
db_table = u'Book'
def __unicode__(self):
return u'%d %s %s' % (self.pk, self.book_name, self.publisher_name)
my forms.py
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['author_id','first_name','last_name','email','age']
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields=['book_id','book_name','publisher_name','author_id']
views.py
def addbook(request):
log.debug("test....")
form = BookForm
if request.POST:
form = BookForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('addbook.html',{'form': form} , context_instance=RequestContext(request))
I am trying to insert the data into database and displaying it through a template.But i ma not sure the code what i used are correct becaues i am getting lots of error.eg recently i got the error as"ValueError: ModelForm has no model class specified.".
But after rectifying this error again errors are coming and not able to save the data to database.
Please check the code's are correct,if not give me the correct code for doing the same.Acutally i think some problem in the views.py.Please check everything and get me the cooect one.
Thanks.

Resources