django - Getting an error after passing on_delete argument - django-models

Creating a game model in django 2.0, by passing on_delete arg in foreign key as well.
from django.db import models
from django.contrib.auth.models import User
class Game(models.Model):
first_player = models.ForeignKey(User,
related_name="games_first_player")
second_player = models.ForeignKey(User,
related_name="games_second_player")
start_time = models.DateTimeField(auto_now_add=True)
last_active = models.DateTimeField(auto_now=True)
Creating a Move model
class Move(models.Model):
x = models.IntegerField()
y = models.IntegerField()
comment = models.charfield(max_length=300, blank=True)
by_first_player = models.BooleanField()
game = models.ForeignKey(Game, on_delete=models.CASCADE)

You forgot th specify the on_delete=... parameter [Django-doc] of your ForeignKeys in your Game model:
from django.contrib.auth import get_user_model
class Game(models.Model):
first_player = models.ForeignKey(
get_user_model(),
related_name='games_first_player',
on_delete=models.CASCADE
)
second_player = models.ForeignKey(
get_user_model(),
related_name='games_second_player'
on_delete=models.CASCADE
)
start_time = models.DateTimeField(auto_now_add=True)
last_active = models.DateTimeField(auto_now=True)
You might want to use get_user_model() [Django-doc] over User, since if you later change your user model, you can easily update all ForeignKeys.

Related

Creating a simple messaging function (NOT REAL TIME) using Django

Please I'm trying to implement a SIMPLE messaging function (NOT A REAL TIME CHAT)
But I keep getting this error message I understand what it says or mean but I'm not sure why I am unable to establish this relationship
Please I need help to alternative if I can't do things this way
This is my profile(Engineer) models
class Engineer(AbstractUser):
username = models.CharField(max_length=200, null=True)
email = models.EmailField(unique=True, null=True)
bio = models.TextField()
avatar = models.ImageField(default="profile.png")
country = models.CharField(max_length=200)
years_of_experience = models.PositiveIntegerField(null=True, blank=True)
tech_stack = models.CharField(null=True, blank=True, max_length=300)
inbox = models.ForeignKey(Inbox, null=True, on_delete=models.CASCADE)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
def __str__(self):
return self.username
and this is my Inbox models
class Inbox(models.Model):
sender = models.ForeignKey(Engineer, null=True, on_delete=models.CASCADE, related_name='mail_sender')
receiver = models.ForeignKey(Engineer, null=True, on_delete=models.CASCADE, related_name="mail_receiver")
message = models.CharField(max_length=500)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created"]
def __str__(self):
return self.sender.username
Just make the Engineer import as follows
sender = models.ForeignKey('Engineer', null=True, on_delete=models.CASCADE, related_name='mail_sender')
receiver = models.ForeignKey('Engineer', null=True, on_delete=models.CASCADE, related_name="mail_receiver")

How do i access another column from related table other than the foreign key, when creating an API view

Im using django for a web app and i am creating REST API views. Is there a way i can access two tables in one view? If not, how can can i retrieve a non-foreign key column from a related record. The below code is retrieving a vase record based on a URL parameter. I want to access the artistName which is stored in artist table (a one-to-many with Vase table), not artist_id which is stored in Vase
class FilterVases(generics.ListAPIView):
serializer_class = VaseSerializer
def get_queryset(self):
queryset = Vase.objects.all()
artist_id = self.request.query_params.get('artist_id')
if artist_id is not None:
queryset = queryset.filter(artist_id=artist_id)
vaseID = self.request.query_params.get('vaseID')
if vaseID is not None:
queryset = queryset.filter(vaseID=vaseID)
return queryset
edited to add
This is models for Artist and Vase:
class Artist(models.Model) :
artistID = models.CharField(max_length=10)
artistName = models.CharField(max_length=100)
class Vase(models.Model):
vaseID = models.CharField(max_length=10)
vaseRef = models.CharField(max_length=255,blank=True,null=True)
inscription = models.CharField(max_length=255,blank=True,null=True)
fabric = models.CharField(max_length=100, blank=True,null=True)
subject = models.CharField(max_length=255,blank=True,null=True)
technique = models.CharField(max_length=100,blank=True,null=True)
height = models.FloatField(max_length=100,blank=True,null=True)
diameter = models.FloatField(max_length=100,blank=True,null=True)
shape = models.ForeignKey(Shape, on_delete=models.CASCADE)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
provenance = models.ForeignKey(Provenance, on_delete=models.CASCADE)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
In the Vase model add this:
def artist_name(self):
return self.artist.artistName
Hence, it will look like:
class Vase(models.Model):
vaseID = models.CharField(max_length=10)
vaseRef = models.CharField(max_length=255,blank=True,null=True)
inscription = models.CharField(max_length=255,blank=True,null=True)
fabric = models.CharField(max_length=100, blank=True,null=True)
subject = models.CharField(max_length=255,blank=True,null=True)
technique = models.CharField(max_length=100,blank=True,null=True)
height = models.FloatField(max_length=100,blank=True,null=True)
diameter = models.FloatField(max_length=100,blank=True,null=True)
shape = models.ForeignKey(Shape, on_delete=models.CASCADE)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
provenance = models.ForeignKey(Provenance, on_delete=models.CASCADE)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
def artist_name(self):
return self.artist.artistName
In the VaseSerializer add the 'artist_name' to the fields Meta.
If you want to add this custom fields to all Vase Model fields, refer to this topic Django Rest framework, how to include '__all__' fields and a related field in ModelSerializer ?
class VaseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Vase
fields = '__all__'
extra_fields = ['artist_name']
def get_field_names(self, declared_fields, info):
expanded_fields = super(VaseSerializer, self).get_field_names(
declared_fields, info)
if getattr(self.Meta, 'extra_fields', None):
return expanded_fields + self.Meta.extra_fields
else:
return expanded_fields
Below should your view:
class FilterVases(generics.ListAPIView):
serializer_class = VaseSerializer
def get_queryset(self):
queryset = Vase.objects.all()
query_artist = self.request.query_params.get('artist_name')
if query_artist is not None:
try:
artist = Artist.objects.get(artistName=query_artist)
queryset = queryset.filter(artist=artist)
except:
pass
vaseID = self.request.query_params.get('vaseID')
if vaseID is not None:
queryset = queryset.filter(vaseID=vaseID)
return queryset

Django rest framework + multiple database + POST data

I'm preparing API and I'm using multiple database ("oracle" and "sqlserver").
I want to POST data (json) into sqlserver.
Here is part of my code.
models.py (every table is in sqlserver database)
class QtOfferParam(models.Model):
ext_id = models.IntegerField(primary_key=True)
dealer_code = models.CharField(max_length=10, db_column="dealer_code")
dealer_name = models.CharField(max_length=30, db_column="dealer_name")
dealer_user = models.CharField(max_length=30, db_column="dealer_user")
class Meta:
db_table = 'ZZ_QT_OFFER_PARAM'
class QtParameterValues(models.Model):
ext_id = models.ForeignKey(QtOfferParam, to_field="ext_id", db_column="ext_id", on_delete=models.PROTECT, related_name="parameterValues", primary_key=True)
parameter = models.CharField(max_length=200, null=True, db_column="parameter")
value_p = models.CharField(max_length=10, null=True, db_column="value_p")
class Meta:
db_table = 'ZZ_QT_PARAMETER_VALUE'
class QtOptions(models.Model):
ext_id = models.ForeignKey(QtOfferParam, to_field="ext_id", db_column="ext_id", on_delete=models.PROTECT, related_name="options", primary_key=True)
f_amount = models.FloatField(db_column="FINANCED_AMOUNT")
installment_amount = models.FloatField(db_column="INSTALLMENT_AMOUNT")
total_amount = models.FloatField(db_column="TOTAL_AMOUNT")
total_amount_in_percentage = models.FloatField(db_column="TOTAL_AMOUNT_IN_PERCENTAGE")
class Meta:
db_table = 'ZZ_QT_OPTIONS'
serializers.py (i added " using='sqlserver' ")
class ReqSerializer(serializers.HyperlinkedModelSerializer):
dealer = DealerField(source='*')
parameterValues = ParametersSgSerializer(many=True)
options = OptionsSgSerializer(many=True)
class Meta:
model = QtOfferParam
fields = ['ext_id', 'dealer', 'parameterValues', 'options']
def create(self, validated_data):
parameters_data = validated_data.pop('parameterValues')
options_data = validated_data.pop('options')
req_id = QtOfferParam.objects.using('sqlserver').create(**validated_data)
for parameters_data in parameters_data:
parameters_data['ext_id'] = req_id
QtParameterValues.objects.using('sqlserver').create(**parameters_data)
for options_data in options_data:
options_data['ext_id'] = req_id
QtOptions.objects.using('sqlserver').create(**options_data)
return req_id
views.py
class testView(viewsets.ModelViewSet):
queryset = QtOfferParam.objects.using('sqlserver').all()
serializer_class = ReqSerializer
when I GET data everything is OK. The data are from sql server, but if I try POST new json i get error from oracle database:
ORA-00942: table or view does not exist
Where i need to add database to save data in sqlserver?

How can I access my models in django admin?

I am working on an AlumniTracker in django and till now I have created forms for user sign up and some additional information.
Even after saving the additional information form I am not able to access it in django-admin.
I am adding my models, views and forms file here.
views.py
def student_profile(request):
if request.method == 'POST':
form = StudentDetailForm(request.POST)
if form.is_valid:
student_form = form.save(commit=False)
student_form.user = request.user
student_form.save()
return redirect(reverse('homepage'))
else:
form = StudentDetailForm()
return render(request, 'authentication/student_profile.html', {'form':form})
def alumni_profile(request):
if request.method == 'POST':
form = AlumniDetailForm(request.POST)
if form.is_valid:
alumni_form = form.save(commit=False)
alumni_form.user = request.user
alumni_form.save()
return redirect(reverse('homepage'))
else:
form = AlumniDetailForm()
return render(request, 'authentication/student_profile.html', {'form':form})
forms.py
class StudentDetailForm(ModelForm):
class Meta:
model = StudentDetail
fields = ['first_name', 'last_name', 'contact_no', 'birth_date', 'course', 'session_start', 'session_end']
class AlumniDetailForm(ModelForm):
class Meta:
model = AlumniDetail
exclude = ['user']
models.py
class CustomUser(AbstractUser):
profile = models.CharField(max_length=10,choices=PROFILE_CHOICES, default='student')
def __str__(self):
return self.username
class StudentDetail(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
contact_no = models.IntegerField()
birth_date = models.DateField()
course = models.CharField(max_length=50)
session_start = models.IntegerField()
session_end = models.IntegerField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class AlumniDetail(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
contact_no = models.IntegerField()
birth_date = models.DateField()
course = models.CharField(max_length=50)
session_start = models.IntegerField()
session_end = models.IntegerField()
company = models.CharField(max_length=60)
open and edit admin.py
and register your models by adding code below admin import
from .models import CustomUser,StudentDetail,AlumniDetail
admin.site.register(CustomUser)
admin.site.register(StudentDetail)
admin.site.register(AlumniDetail)

django insert data from 2 tables using a single ModelForm

I want to get data from 2 tables into a form using ModelForm, like this:
fist model:
class Cv(models.Model):
created_by = models.ForeignKey(User, blank=True)
first_name = models.CharField(('first name'), max_length=30, blank=True)
last_name = models.CharField(('last name'), max_length=30, blank=True)
url = models.URLField(verify_exists=True)
picture = models.ImageField(help_text=('Upload an image (max %s kilobytes)' %settings.MAX_PHOTO_UPLOAD_SIZE),upload_to='avatar')
bio = models.CharField(('bio'), max_length=180, blank=True)
expertise= models.ForeignKey(Expertise, blank=True)
date_birth = models.DateField()
second model:
class Expertise(models.Model):
user = models.ForeignKey(User, blank=True)
domain = models.CharField(('domain'), max_length=30, blank=True)
specialisation = models.CharField(('specialization'), max_length=30, blank=True)
degree = models.CharField(('degree'), max_length=30, blank=True)
year_last_degree = models.CharField(('year_last_degree'), max_length=30, blank=True)
lyceum = models.CharField(('lyceum'), max_length=30, blank=True)
faculty = models.CharField(('faculty'), max_length=30, blank=True)
references = models.CharField(('references'), max_length=30, blank=True)
workplace = models.CharField(('workplace'), max_length=30, blank=True)
then i have in forms.py
class CvForm(ModelForm):
class Meta:
model = Cv
fields = ['first_name','last_name','url','picture','bio','date_birth']
class ExpertiseForm(ModelForm):
class Meta:
model = Expertise
fields = ['domain','specialisation']
The point is that i would want to have the both forms into one single form, and a single submit of course. So, i guess i should use a single ModelForm type class. But it doesn't work (if i put the expertise in the CvForm too ).
My form is created automatically from the ModelForm class, that's why i want to make a single class = > a single form.
Help plss,
Thanks a lot
Since there is a foreign key from Expertise to CV, there are potentially multiple expertises for each cv. So you should enable that by using inline formsets.

Resources