I am trying to save data into a mysql database using 2 tables main and public, but am unable to store data into the public table.
ERROR: ValueError: Cannot assign "4": "public.unq_id" must be a "main" instance.
Models.py:
class main(models.Model):
unq_id = models.BigAutoField(primary_key=True)
email = models.CharField(max_length=80)
password = models.CharField(max_length=256)
first_name = models.CharField(max_length=80)
last_name = models.CharField(max_length=80)
dob = models.CharField(max_length=80)
phone = models.BigIntegerField(default=0)
status = models.CharField(max_length = 12, default = 'active')
def __str__(self):
return self.unq_id
def verify_password(self, raw_password):
return pbkdf2_sha256.verify(raw_password, self.password)
class public(models.Model):
unq_id = models.OneToOneField(main, on_delete=models.CASCADE, primary_key = True)
lang = models.CharField(max_length=80)
expert = models.CharField(max_length=80)
country = models.CharField(max_length=80, default = "None")
Views.py:
Email1=request.POST['Email']
a = main.objects.filter(email = Email1).exists()
if a is True:
error = "Email taken"
return render(request, 'Main/registration.html',{'error':error})
password1=request.POST['password']
password = pbkdf2_sha256.encrypt(password1,rounds=12000,salt_size=32)
Fname=request.POST['Fname']
Lname=request.POST['Lname']
DOB=request.POST['dob2']
lang= request.POST['lang']
phone=request.POST['phone']
c = main.objects.filter(phone = phone).exists()
if c is True:
error = "phone number taken"
return render(request, 'Main/registration.html',{'error3':error})
country=request.POST['country']
r = countrycode.objects.filter(country = country).exists()
if r is True:
s = countrycode.objects.get(country = country)
country = s.code
main2=main(email=Email1,password=password,first_name=Fname,last_name=Lname,dob=DOB,phone=phone)
main2.save()
mainobj= main.objects.get(email = Email1)
public2=public(lang=lang,expert="false",country=country,unq_id=mainobj.unq_id)
public2.save()
When I look in my database, the mainobj gets stored but the public object doesn't get saved; despite having the same "unq_id"
Please do help , thank you
The error is telling you that when you instantiate the public object you are trying to pass a "4" string / int, as an unq_id parameter when in fact you defined a OneToOne relation that is at the instance level relationship, so your public object in the unq_id attribute expects an object / instance of main.
Example:
main_test = main(email='test#test.com', password='test', ...)
public_test = public(unq_id=main_test,...)
In the Django documentation you can find all the aspects about this type of relationship, such as its restrictions or how the objects are retrieved when a query is made to the DB.
Related
In a Django Modelform (Product_definition), i want to have a dropdown(Merchant name) which will show users only if the their designation in User form is "Merchant".
is it possible that I could get the list of users for the dropdown based on this condition .Please note that i don't require it to be a foreign key as connecting the models is not required.
This is the form which contains the Designation :
from django.contrib.auth.models import User
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete = models.CASCADE)
#extra UserAttribute
MERCHANT = 'MR'
FABRIC = 'FR'
WASHING = 'WS'
PRINT = 'PR'
PLANNER = 'PL'
DESIGNATION_CHOICES =(
(PLANNER,'Planner'),
(MERCHANT,'Merchant'),
(FABRIC,'Fabric'),
(WASHING,'Washing'),
(PRINT,'Printing'),
)
Designation =models.CharField(
max_length = 20,
choices = DESIGNATION_CHOICES,
default= 'PLANNER'
)
def __str__(self):
return self.user.username
and this is the form with Merchant Name where I want the names of all merchants to appear.
class Product_definition(models.Model):
Order_number = models.CharField(max_length=25,unique = True, blank = True, null = True)
style_name = models.CharField(max_length=15, blank = True, null = True)
color = models.CharField(max_length=15, blank = True, null = True)
Order_qty = models.PositiveIntegerField()
SMV = models.FloatField()
MERCHANT = models.ForeignKey(UserProfileInfo,on_delete= models.CASCADE,default='Select')
def __str__(self):
return self.Order_number
I have created a foreign key for now but I don't require it and it doesn't list the names of only the merchant in the drop down.
I think you can do it like this using ModelChoiceField:
class ProductForm(forms.ModelForm): # please use CamelCase when defining Class Names
MERCHANT = forms.ModelChoiceField(queryset=UserProfileInfo.objects.filter(Designation=UserProfileInfo.MARCHENT)) # Please use sname_case when naming attributes
class Meta:
model = Product_definition # Please use CamelCase when defining model class name
fields = '__all__'
In my postgressql database I have tables:
class Topic(models.Model):
Definition = models.TextField(default='Definition')
Name = models.TextField(default='Name')
def __str__(self):
return self.Name
class Question(models.Model):
Statement = models.TextField(default='Question')
def __str__(self):
return self.Statement
class Planit_location(models.Model):
Planit_location = models.CharField(max_length=255, default='Planit_location')
def __str__(self):
return self.Planit_location
class ClientDetail(models.Model):
Sector = models.ForeignKey(Sector, on_delete=models.CASCADE)
Client_name = models.CharField(max_length=255, default='Client_name')
def __str__(self):
return self.Client_name
class Response(models.Model):
Question = models.ForeignKey(Question, on_delete=models.CASCADE)
Topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
Response = models.TextField(default='Response')
Client = models.ForeignKey(ClientDetail, on_delete=models.CASCADE)
Planit_Location = models.ForeignKey(Planit_location, on_delete=models.CASCADE)
Image = models.ForeignKey(Image, on_delete=models.CASCADE)
def __str__(self):
return self.Response
I want to create a modelform using all these tables so I can add new questions and responses to my database, which are then linked to a topic, location and client (these 3 will be a dropdownlist from data in db).
I have managed to create a modelform for just question and response but when I try to submit it I get "null value in column "Question_id" violates not-null constraint"
Here is the code:
if request.method == 'POST':
qform = QuestionForm(request.POST)
rform = ResponseForm(request.POST)
if qform.is_valid() and rform.is_valid():
qf = qform.save()
rf = rform.save()
return render(request, 'app/adddatatest.html', {
"qform": QuestionForm(),
"rform": ResponseForm(),
})
After checking for is_valid() in view do this:
qf = qform.save() # Goes to database
rf = rform.save(commit=False) # Doesn't goes to database
rf.Question = qf # gets required attribute
rf.save() # then goes to database
You can't save Response object without specifying the the foreign key Question. So in rform.save pass argument commit=False to not actually saving it in database yet. Then add the value for the foreign key to the new created Response object, foreign key is required otherwise you will get IntegrityError. Then finally save it to the database.
I have a generic model called 'Phone':
(my_project/apps/phones/models.py)
class Phone(Model):
owner_name = CharField(max_length=50)
number = CharField(max_length=20)
content_type = ForeignKey(ContentType, on_delete=CASCADE)
object_id = PositiveIntegerField()
phone_object = GenericForeignKey('content_type', 'object_id')
I also have a model called 'Client':
(my_project/apps/clients/models.py)
class Client(Model):
employee = ForeignKey(Employee, on_delete=CASCADE)
title = CharField(max_length=50)
phones = GenericRelation(Phone)
I also have a serializer for 'Client':
(my_project/apps/clients/serializers.py)
class ClientSerializer(ModelSerializer):
id = IntegerField(read_only=True)
employee_id = PrimaryKeyRelatedField(queryset=Employee.objects.all(), source='employee', required=True)
title = CharField(required=True)
I followed drf-documenation (http://www.django-rest-framework.org/api-guide/relations/#generic-relationships), and as I understood I need to put custom class in the same file, so here is how my clients/serializers.py looks like:
(my_project/apps/clients/serializers.py)
class ClientSerializer(ModelSerializer):
id = IntegerField(read_only=True)
employee_id = PrimaryKeyRelatedField(queryset=Employee.objects.all(), source='employee', required=True)
title = CharField(required=True)
class PhoneObjectRelatedField(RelatedField):
def to_representation(self, value):
if isinstance(value, Client):
serializer = ClientSerializer(value)
else:
raise Exception('Unexpected type of phone_object')
return serializer.data
For requests I am using PostMan, so here is my request to Create new Client with phone number:
But it does nothing, new Clients can be created successfully but they just don't contain any phone numbers, please help!
You can add the related field to the serializer fields
class ClientSerializer(ModelSerializer):
id = IntegerField(read_only=True)
employee_id = PrimaryKeyRelatedField(queryset=Employee.objects.all(), source='employee', required=True)
title = CharField(required=True)
phone = PhoneObjectRelatedField()
update by #Madi7
phone = PhoneObjectRelatedField(queryset=Phone.objects.all())
I have this Error :
IntegrityError at /api/post_flight_schedule/
NOT NULL constraint failed: flights_tailnumber.aircraft_type_id
When I try to add a new PosFlightSchedule object to DB over http://127.0.0.1:8000/api/pos_flight_schedule (Website/APIView)
I have the below serializer :
class PosFlightScheduleModelSerializer(ModelSerializer):
class Meta:
model = PosFlightSchedule
fields = ['pos_route_id', 'tail_number', 'pos_flight_number', 'pos_flight_departure_time', 'pos_flight_date',
'pax_count']
class PosFlightScheduleSerializer(serializers.Serializer):
pos_route_id = serializers.CharField(source='pos_route_id.route_id', read_only=False)
tail_number = serializers.CharField(source='tail_number.tail_number', read_only=False)
pos_flight_number = serializers.CharField(source='pos_flight_number.flight_number', read_only=False)
pos_flight_departure_time = serializers.CharField(source='pos_flight_departure_time.flight_departure_time', allow_null=True,
read_only=False)
pos_flight_date = serializers.CharField(source='pos_flight_date.flight_date', read_only=False)
pax_count = serializers.IntegerField(read_only=False)
def create(self, validated_data):
tail_number_data = validated_data.pop("tail_number")
tail_number = TailNumber.objects.create(**tail_number_data)
flight_number_data = validated_data.pop("pos_flight_number")
flight_number = FlightSchedule.objects.create(**flight_number_data)
flight_departure_time_data = validated_data.pop("pos_flight_departure_time")
print "DEP_TIME" + str(flight_departure_time_data)
flight_departure_time = FlightSchedule.objects.create(**flight_departure_time_data)
route_id_data = validated_data.pop("pos_route_id")
route_id = FlightScheduleDetail.objects.create(**route_id_data)
flight_date_data = validated_data.pop("pos_flight_date")
flight_date = FlightScheduleDetail.objects.create(**flight_date_data)
pax_count = validated_data.pop("pax_count")
schedule_obj = PosFlightSchedule.objects.create(**validated_data)
# if tail_number:
schedule_obj.set_tail_number(tail_number)
schedule_obj.set_pos_flight_number(flight_number)
schedule_obj.set_pos_flight_departure_time(flight_departure_time)
schedule_obj.set_pos_route_id(route_id)
schedule_obj.set_pos_flight_date(flight_date)
schedule_obj.set_pax_count(pax_count)
schedule_obj.save()
return schedule_obj
def update(self, instance, validated_data):
tail_number = validated_data.pop("tail_number")
flight_number = validated_data.pop("pos_flight_number")
flight_departure_time = validated_data.pop("pos_flight_departure_time")
route_id = validated_data.pop("pos_route_id")
flight_date = validated_data.pop("pos_flight_date")
pax_count = validated_data.pop("pax_count")
instance.__dict__.update(validated_data)
if tail_number:
instance.set_tail_number(tail_number)
if flight_number:
instance.set_pos_flight_number(flight_number)
if flight_departure_time:
instance.set_pos_flight_departure_time(flight_departure_time)
if route_id:
instance.set_pos_route_id(route_id)
if flight_date:
instance.set_pos_flight_date(flight_date)
if pax_count:
instance.set_pax_count(pax_count)
instance.save()
return instance
The model of the field which is giving error looks like :
class TailNumber(models.Model):
tail_number_id = models.AutoField(null=False, primary_key=True)
tail_number = models.CharField(max_length=20, null=False, blank=False, unique=True)
aircraft_type = models.ForeignKey(AircraftType, null=False, blank=False)
def __unicode__(self):
return u'%s' % self.tail_number
class Meta:
verbose_name_plural = "Tail Numbers"
I am not understanding what is going wrong here.
The error you get is probably due to the fact that the dictionary tail_number_data does not contain the keyword aircraft_type, which is expected by TailNumber.objects to create the row in the db, since you defined it with no possibility to be null
aircraft_type = models.ForeignKey(AircraftType, null=False, blank=False)
^^^^^
Check that the key "aircraft_type" does exist in the dictionary tail_number_data, or allow for it to be null. Furthermore, if you consider the latter option and that this information is supposed to come from a UI, you may also want to allow for aircraft_type to be blank. See differentiate null=True, blank=True in django for details.
I want to do a query on the django User table like this:
u = User.objects.filter(member__in = member_list)
where:
class Member(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
dob = models.DateField('Date of Birth', blank=True, null=True)
and member_list is a list of eligible members.
The query works fine but the problem is I do not actually know the model member is called member. It could be called anything.
I store the name of the model I want in a model called Category. I have a link to the name of the model through content_type.Category is defined as:
class Category(models.Model):
name = models.CharField('Category', max_length=30)
content_type = models.ForeignKey(ContentType)
filter_condition = JSONField(default="{}", help_text=_(u"Django ORM compatible lookup kwargs which are used to get the list of objects."))
user_link = models.CharField(_(u"Link to User table"), max_length=64, help_text=_(u"Name of the model field which links to the User table. 'No-link' means this is the User table."), default="No-link")
def clean (self):
if self.user_link == "No-link":
if self.content_type.app_label == "auth" and self.content_type.model == "user":
pass
else:
raise ValidationError(
_("Must specify the field that links to the user table.")
)
else:
if not hasattr(apps.get_model(self.content_type.app_label, self.content_type.model), self.user_link):
raise ValidationError(
_("Must specify the field that links to the user table.")
)
def __unicode__(self):
return self.name
def _get_user_filter (self):
return str(self.content_type.app_label)+'.'+str(self.content_type.model)+'.'+str(self.user_link)+'__in'
def _get_filter(self):
# simplejson likes to put unicode objects as dictionary keys
# but keyword arguments must be str type
fc = {}
for k,v in self.filter_condition.iteritems():
fc.update({str(k): v})
return fc
def object_list(self):
return self.content_type.model_class()._default_manager.filter(**self._get_filter())
def object_count(self):
return self.object_list().count()
class Meta:
verbose_name = _("Category")
verbose_name_plural = _("Categories")
ordering = ('name',)
So I can retrieve the name of the model that links to User but I then need to convert it into a class which I can include in a query.
I can create an object x = category.content_type.model_class() which gives me <class 'cltc.models.Member'> but when I them perform a query s = User.objects.filter(x = c.category.object_list()) I get the error Cannot resolve keyword 'x' into field.
Any thoughts most welcome.
The left hand side of the filter argument is a keyword, not a python object, so x is treated as 'x', and Django expects a field called x.
To get around this, you can ensure that x is a string, and then use the python **kwarg syntax:
s = User.objects.filter(**{x: c.category.object_list()})
Thanks to https://stackoverflow.com/a/4720109/823020 for this.