how to insert data into database using forms in Django - django-models

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.

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

Unable to pass django model object to serializer

I am trying to pass a django model object to a field in a serializer that is for a foreign key field in the model. However, I get the error: "Object of type AuthorUser is not JSON serializable."
Here is the model the serializer is for:
class Article(models.Model):
title = models.CharField(max_length=200, unique=True)
author = models.ForeignKey(AuthorUser, on_delete=models.CASCADE)
body = models.TextField()
posted=models.BooleanField(default=False)
edited = models.BooleanField(default=False)
ready_for_edit = models.BooleanField(default=False)
Here is the serializer (author is the field specifically that is giving me trouble):
class CreateArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['title', 'body', 'author']
And here is the view that has the code that causes the error (the POST method is the part that causes the error):
#api_view(['GET', 'POST'])
def articles(request):
if request.method == 'GET':
articles = Article.objects.all()
serializer = CreateArticleSerializer(articles, many=True)
return Response(serializer.data)
if request.method == 'POST':
if request.user.is_authenticated:
author = AuthorUser.objects.get(id=request.data['author'])
request.data['author'] = author
print(request.data)
serializer = CreateArticleSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return HttpResponse(status=401)
Any help is appreciated! Just to let you know, when creating these articles using an id, it works, however, it creates a new field in Article called author_id. Then when I try to access author it gives me author_id so that doesn't work.
You need to change your serializer as follows:
class CreateArticleSerializer(serializers.ModelSerializer):
author = serializers.SlugRelatedField(queryset=AuthorUser.objects.all(),
slug_field='id')
class Meta:
model = Article
fields = ['title', 'body', 'author']
Now if you will pass id in your view while calling serializer it will create the object of model. Hope this will work for you.

Filtering the results in the dropdown for foreign key in Django rest framework

I have 3 models. User, process, processmapping. process model has a created_by filed which is a foreign key to user model. processmapping model has processname filed which is a foreign key to process table.
My code is as follows.
models.py
class process(models.Model):
created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column= "username")
process_name = models.CharField(max_length=200)
....
class processmap(models.Model):
process = models.ForeignKey(process, on_delete=models.CASCADE, db_column="process_name")
....
views.py
class processViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
queryset= process.objects.all()
serializer_class = processSerializer
filter_backends = (DjangoFilterBackend,filters.SearchFilter)
filter_fields = ('created_by', 'process_name',)
def get_queryset(self):
if self.request.user.is_superuser:
return self.queryset
else:
queryset = self.queryset
query_set = queryset.filter(created_by=self.request.user)
return query_set
class processmapViewset(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
try:
queryset= processmap.objects.all()
serializer_class = processmapSerializer
filter_backends = (DjangoFilterBackend,filters.SearchFilter)
filter_fields = ('process', 'service', 'sequence','process__created_by')
Serializers.py
class processSerializer(serializers.HyperlinkedModelSerializer):
#created_by = UserSerializer(many=True)
class Meta:
model = process
fields = ("__all__")
def perform_create(self, serializer):
serializer.save(user=self.request.user)
class processmapSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = processmap
fields = ("__all__")
def perform_create(self, serializer):
serializer.save(user=self.request.user)
When a user creates a process and then goes to mapping the process, the foreign key lists all the processes that are present in the process table. Instead, I need to list down only the processes that are created by the user logged in. How can I achieve this.
Note: I have searched for the same and most answers involve forms. Please note I'm not using any forms and I want that logic to be implemented in the views.py.
Thanks in advance :)

form need shows from the models.py

every one ,,I have
models.py
......
class Place(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
release = models.DateTimeField(blank=True, null=True)
def __unicode__(self):
return self.name
class ProductsTbl(models.Model):
......
place = models.ManyToManyField(Place)
......
def __unicode__(self):
return self.name
and I have forms.py here
forms.py
from django.forms import ModelForm
from .models import *
class ProductsTblForm(ModelForm):
class Meta:
model = ProductsTbl
fields = ('place',)
......
however,,I need let my templates shows the 'release' in form,,right now,,it only shows the 'name' which under the Class place(models.Model): but no 'release',,how can I let the 'release' can show up?
You can access model instance variables in the form by using form.instance.<field_name>.

Django modelformset form is not blank when I return

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')

Resources