I need to update fields on import for ManyToMany bulk editing.
When importing, now I can only add products, because when I try to add already existing fields, I get a message about already existing IDs.
How can I update products using import?
admin.py
class ProductResource(resources.ModelResource):
class Meta:
model = Part
class PartAdmin(ImportExportActionModelAdmin):
resource_class = ProductResource
filter_horizontal = ('analog',)
admin.site.register(Part, PartAdmin)
models.py
class Part(models.Model):
brand = models.CharField('Производитель', max_length=100)
number = models.CharField('Артикул', max_length=100, unique=True)
name = models.CharField('Название', max_length=100)
description = models.TextField('Комментарий', blank=True, max_length=5000)
analog = models.ManyToManyField('self', blank=True, related_name='AnalogParts')
images = models.FileField('Главное изображение', upload_to = 'parts/', blank=True)
images0 = models.FileField('Дополнительное фото', upload_to = 'parts/', blank=True)
images1 = models.FileField('Дополнительное фото', upload_to = 'parts/', blank=True)
images2 = models.FileField('Дополнительное фото', upload_to = 'parts/', blank=True)
def __str__(self):
return str(self.brand + " " + self.number + " " + self.name)
return self.name
from django.contrib import admin
from .models import *
from import_export.admin import ImportExportActionModelAdmin
from import_export import resources
from import_export import fields
from import_export.widgets import ForeignKeyWidget
class ProductResource(resources.ModelResource):
#category = fields.Field(column_name='Артикул', attribute='number')
class Meta:
model = Part
import_id_field = 'number'
import_id_fields = ('number',)
def skip_row(self, instance, original):
original_id_value = getattr(original, self._meta.import_id_field)
instance_id_value = getattr(instance, self._meta.import_id_field)
if original_id_value != instance_id_value:
return True
if not self._meta.skip_unchanged:
return False
for field in self.get_fields():
try:
if list(field.get_value(instance).all()) != list(field.get_value(original).all()):
return False
except AttributeError:
if field.get_value(instance) != field.get_value(original):
return False
return True
admin.site.register(Kits)
class PartAdmin(ImportExportActionModelAdmin):
resource_class = ProductResource
filter_horizontal = ('analog',)
admin.site.register(Part, PartAdmin)
#class PartAdmin(admin.ModelAdmin):
# filter_horizontal = ('analog',)
#admin.site.register(Part, PartAdmin)
Related
I am trying to import data from a csv using Django_Import Export. I saw other SO posts but they are not helping. Below are the models
Models.py
class TblSubject(amdl.AagamBaseModel):
subject_id = models.AutoField(primary_key=True)
subject_name = models.CharField(max_length=20)
standard = models.ForeignKey('TblStandard', models.DO_NOTHING)
remembrance_credit = models.IntegerField(default=40)
applied_knowledge_credit = models.IntegerField(default=30)
understanding_credit = models.IntegerField(default=30)
subject_credit = models.IntegerField(default=100)
class Meta:
db_table = 'tblsubject'
def __str__(self):
return f'{self.subject_name}'
class SubjectChapter(amdl.AagamBaseModel):
subject_chapter_id = models.AutoField(primary_key=True)
subject = models.ForeignKey('TblSubject', on_delete=models.CASCADE)
chapter_id = models.IntegerField()
chapter_name = models.CharField(max_length=150)
remembrance_credit = models.IntegerField()
applied_knowledge_credit = models.IntegerField()
understanding_credit = models.IntegerField()
chapter_credit = models.IntegerField()
class Meta:
db_table = 'subject_chapter'
def __str__(self):
return f'{self.chapter_id} {self.chapter_name} : {self.subject}'
Here is the admin.py
from django.contrib import admin
from import_export import resources, fields
from import_export.widgets import ForeignKeyWidget
from .models import SubjectChapter, TblSubject
from import_export.admin import ImportExportModelAdmin
class SubjectChapterResource(resources.ModelResource):
class Meta:
model = SubjectChapter
import_id_fields = ('subject_chapter_id',)
subject = fields.Field(
column_name='subject_name',
attribute='subject_name',
widget=ForeignKeyWidget(TblSubject, 'subject_id'))
class SubjectChapterAdmin(ImportExportModelAdmin):
resource_class = SubjectChapterResource
admin.site.register(SubjectChapter, SubjectChapterAdmin)
And i am getting this below error
I am inserting data for SUBJECTCHAPTER from csv where the SUBJECT column is a foreign key from TBLSUBJECT and it contains the name of the TBLSUBJECT.
Change this
class SubjectChapterResource(resources.ModelResource):
class Meta:
model = SubjectChapter
import_id_fields = ('subject_chapter_id',)
subject = fields.Field(
column_name='subject_name',
attribute='subject_name',
widget=ForeignKeyWidget(TblSubject, 'subject_name'))
From subject_id to subject_name
I am trying to count the number of the student according to CourseMasterModel.
I did it in MySQL, but I want to in Django.
select cn.course_name,count(st.id) from course_master
cn,semister_master sem,division_master di,student_profile st where
st.division_id = di.id and di.semister_id = sem.id and sem.course_id =
cn.id GROUP BY cn.course_name;
class CourseMasterModel(models.Model):
course_name = models.CharField(max_length=20,unique=True)
total_semister = mod`enter code here`els.SmallIntegerField()
class Meta:
db_table = "course_master"
verbose_name_plural = 'Course (Department)'
verbose_name = "Course"
def __str__(self):
return self.course_name
class SemisterMasterModel(models.Model):
semister = models.SmallIntegerField()
total_div = models.SmallIntegerField()
course = models.ForeignKey(CourseMasterModel,on_delete=models.PROTECT)
class Meta:
db_table = "Semister_master"
verbose_name_plural = 'Semister'
verbose_name = "semister"
def __str__(self):
return "%s - %d" %(self.course.course_name,self.semister)
class DevisionMasterModel(models.Model):
div_name = models.CharField(max_length=2)
semister = models.ForeignKey(SemisterMasterModel,on_delete=models.CASCADE)
class Meta:
db_table = "division_master"
verbose_name_plural = 'Division'
verbose_name = "Division"
def __str__(self):
return "%s - %s - %s"%(self.semister.course.course_name,self.semister.semister,self.div_name)
class StudentProfileModel(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,related_name="profile")
division = models.ForeignKey('core.DevisionMasterModel',on_delete=models.CASCADE,verbose_name="Course / Semister / Division")
roll_no = models.IntegerField()
enrollment_no = models.IntegerField(unique=True, error_messages={'unique':"This enrollment number has already been registered."})
def __str__(self):
return self.user.username
class Meta:
db_table = "Student_Profile"
You can annotate your CourseMasterModel, like:
from django.db.models import Count
CourseMasterModel.objects.annotate(
nstudents=Count('semistermastermodel__devisionmastermodel__studentprofilemodel')
)
The CourseMasterModels that arise from this QuerySet have an extra attribute .nstudents that contains the number of related StudentProfileModels.
Note: usually the names of Django models have no Model suffix, so CourseMaster instead of CourseMasterModel.
In case you rename the models, the query is:
from django.db.models import Count
CourseMasterModel.objects.annotate(
nstudents=Count('semistermaster__devisionmaster__studentprofile')
)
I get this error when I register the Personel form; "Exception Value: Cannot assign "5": "db_PERSONEL.db_departman" must be a "db_DEPARTMAN" instance. ".
Thanks.
departman_app.model.py
from django.db import models
class db_DEPARTMAN(models.Model):
id = models.AutoField(primary_key=True, editable=False)
db_departmanAdi = models.CharField(max_length = 50)
def __unicode__(self):
return u'%s' % (self.db_departmanAdi)
personel_app.models.py
from django.db import models
from departman.models import db_DEPARTMAN
class db_PERSONEL(models.Model):
id = models.AutoField(primary_key=True, editable=False)
db_personelAdi = models.CharField(max_length = 50)
db_departmanAdi = models.ForeignKey(db_DEPARTMAN, on_delete=models.DO_NOTHING, related_name="tags")
def __unicode__(self):
return u'%s' % (self.db_departmanAdi)
personel_app.personelform.py
from django import forms
from personel.models import db_PERSONEL
class personelForm(forms.ModelForm):
class Meta:
model=db_PERSONEL
#fields="__all__"
fields = [
'db_personelAdi',
'db_departmanAdi',
]
form = personelForm()
form.base_fields['db_personelAdi'] = forms.CharField(label='Personel Adı:', max_length=50, widget=forms.TextInput(attrs={'class': 'form-control'}))
form.base_fields['db_departmanAdi'] = forms.IntegerField(label='Deaprtman Adı:', widget=forms.TextInput(attrs={'class': 'form-control'}))
I have been working on a project in which I have to point out the expenses that the workers of a company have.
For this I have created two models, workers and expenses, in which expenses has a foreign key to workers, in the field: "nomTreballador".
When I try to save it in the db I get the error: "Cannot assign "u'Joan Manel'": "despesa.nomTreballador" must be a "treballador" instance."
My models.py:
from __future__ import unicode_literals
from django.db import models
from django.core.validators import RegexValidator
KILOMETRATGE = 'KM'
DINAR = 'DIN'
AUTOPISTA = 'AP'
MANTENIMENTPC = 'PC'
GASTOS = (
(KILOMETRATGE, 'Kilometres'),
(DINAR, 'Dinar'),
(AUTOPISTA, 'Autopista peatge'),
(MANTENIMENTPC, 'Manteniment de pc')
)
NIF = 'NIF'
NIE = 'NIE'
DNI = 'DNI'
TIPUSDOC = (
(DNI, 'DNI'),
(NIF, 'NIF'),
(NIE, 'NIE')
)
class treballador(models.Model):
nom = models.CharField(max_length=150, null=False, unique=True)
cognom = models.CharField(max_length=150, null=False)
tipusDocID = models.CharField(max_length=3, choices=TIPUSDOC, null=False)
docId = models.CharField(max_length=9, null=False)
tlf_regex = RegexValidator(regex=r'^\d{9,9}$',message="Phone number must be entered in the format: '+999999999'. Up to 9 digits allowed.")
tlf = models.CharField(validators=[tlf_regex], blank=True, max_length=9) # validators should be a list
correu = models.EmailField(max_length=254)
ciutat = models.CharField(max_length=150)
dataDAlta = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return unicode(self.nom) or 'u'
class despesa(models.Model):
nomTreballador = models.ForeignKey(treballador, to_field='nom')
tipusDeGast = models.CharField(max_length=3, choices=GASTOS)
quantia = models.DecimalField(max_digits=5, decimal_places=2)
data = models.DateTimeField()
def __unicode__(self):
return unicode(self.nomTreballador) or 'u'
My forms.py:
from django import forms
from functools import partial
from .models import despesa, treballador
DateInput = partial(forms.DateInput, {'class':'datepicker'})
class desModelForm(forms.ModelForm):
data = forms.DateField(widget=DateInput(format='%d/%m/%Y'), label="Data de la despesa", input_formats=['%d/%m/%Y'])
iquery = treballador.objects.values_list('nom', flat=True).distinct()
iquery_choices = [('','None')] + [(treballador,treballador) for treballador in iquery]
nomTreballador = forms.ChoiceField(choices=iquery_choices)
class Meta:
model= despesa
fields= ["nomTreballador","tipusDeGast","quantia","data"]
def clean_despesa(self):
despeses = self.cleaned_data.get("tipusDeGast")
return despeses
def clean_date(self):
date = self.cleaned_data.get("data")
return date
def clean_quantia(self):
quantia = self.cleaned_data.get("quantia")
return quantia
def clean_nom(self):
nomTreballador = self.cleaned_data.get("nomTreballador")
return nomTreballador
My views.py:
from django.shortcuts import render
from .forms import desModelForm, treballadorForm
from .models import treballador, despesa
def home(request):
form = desModelForm(request.POST or None)
context = {
"gast_form": form
}
if form.is_valid():
desp = form.save(commit=False)
desp.save()
return render(request, "imputacioDespeses.html", context)
I've tried solutions of similar questions but I have not managed to solve it
Thank you!!
You are getting this error because you are passing a text string to be used as the nomTreballador foreign key, while you should be passing a treballador instance.
It looks like you're trying to restrict the available choices to a set of distinct trebelladors by using a forms.ChoiceField, but a better way to do this with a ModelForm is to change the queryset attribute of the nomTreballador field. You do this in the form's init method:
self.fields['nomTreballador'].queryset = treballador.objects.all().distinct()
Also you should check the clean methods you've implemented because not all of them map to an existing field.
Hello i have the following problem (sorry for my bad english)
I have the following models
I have 3 models which "Prediccion" has two foreign keys from "Juego" model and "Usuario"model
class Juego(models.Model):
#id = models.IntegerField(primary_key=True, db_column='Id')
equipoa = models.CharField(max_length=135, db_column='EquipoA')
equipob = models.CharField(max_length=135, db_column='EquipoB')
resultadoa = models.IntegerField(null=True, db_column='ResultadoA', blank=True)
resultadob = models.IntegerField(null=True, db_column='ResultadoB', blank=True)
fecha = models.DateField(null=True, db_column='Fecha', blank=True)
class Meta:
db_table = u'juego'
class Usuario(models.Model):
# id = models.IntegerField(primary_key=True, db_column='Id') # Field name made lowercase.
nombre = models.CharField(max_length=135, db_column='Nombre')
fechanacimiento = models.DateField(null=True, db_column='FechaNacimiento', blank=True)
nombreusuario = models.CharField(max_length=135, db_column='NombreUsuario')
clave = models.CharField(max_length=135, db_column='Clave')
class Meta:
db_table = u'usuario'
class Prediccion(models.Model):
#id = models.IntegerField(primary_key=True, db_column='Id')
idusuario = models.ForeignKey(AuthUser, db_column='IdUsuario')
idjuego = models.ForeignKey(Juego, db_column='IdJuego') # Field name made lowercase.
equipoa = models.IntegerField(null=True, db_column='EquipoA', blank=True)
equipob = models.IntegerField(null=True, db_column='EquipoB', blank=True)
resultado = models.IntegerField(null=True, db_column='Resultado', blank=True)
class Meta:
db_table = u'prediccion'
And have I have the following view
from django.shortcuts import render_to_response
from scorecenter.JuegoApp.models import Juego
from scorecenter.PrediccionApp.models import Prediccion
from scorecenter.PrediccionApp.models import TipoResultado
from scorecenter.PrediccionApp.models import AuthUser
def juegosap(request, pagina="1", idgame=-1, resa=-1, resb=-1):
if(idgame==-1 and resa==-1 and resb==-1):
pag = int(pagina)
pag = pag-1
lista = Juego.objects.order_by('-fecha', '-id')[pag*4:pag*4+4]
template_name = 'juegos_semana.html'
return render_to_response(template_name,{'lista':lista})
else:
game = Juego.objects.get(id=int(idgame))
print(game.equipoa)
print(game.id)
user = AuthUser.objects.get(username=request.user)
print(user.username)
temporal = Prediccion(idusuario = user, idjuego = game, equipoa=int(resa), equipob=int(resb))
temporal.resultado = 1
temporal.save()
pag = int(pagina)
pag = pag-1
lista = Juego.objects.order_by('-fecha')[pag*4:pag*4+4]
template_name = 'juegos_semana.html'
return render_to_response(template_name,{'lista':lista})
But I am getting the following error:
Cannot assign "<Juego: Juego object>": "Prediccion.idjuego" must be a "Juego" instance.
in the next line:
temporal = Prediccion(idusuario = user, idjuego = game, equipoa=int(resa), equipob=int(resb))
your idjuego is a foreign key so the value must equivalent to id,
try:
temporal = Prediccion(idusuario = user, idjuego = game.id, equipoa=int(resa), equipob=int(resb))
Also, in each of your model, please put unicode so that it will not return "< object >". Here is a sample:
def __unicode__(self):
return self.field_name
temporal.idjuego_id = game.id
temporal.save()
ForeignKey fields store their value in an attribute with _id at the end, which you can access directly to avoid visiting the database.
The _id version of a ForeignKey is a particularly useful aspect of Django, one that everyone should know and use from time to time when appropriate.