hi i have a problem with this filter. group_to_add takes some values which should filter out the problem that I don't want those values but I want the others without those.
I would like to find a way to take those values and subtract them from others.
group_to_add = DatiGruppi.objects.filter(gruppi_scheda = scheda.id)
GruppiForm.base_fields['dati_gruppo'] = forms.ModelChoiceField(queryset = group_to_add)
I asked a similar question I leave the link
select filtering and removal if they are already present in the db
models
class Schede(models.Model):
nome_scheda = models.CharField(max_length=100)
utente = models.ForeignKey(User, on_delete = models.CASCADE,related_name = 'utente')
class DatiGruppi(models.Model):
dati_gruppo = models.ForeignKey(Gruppi,on_delete = models.CASCADE, related_name = 'dati_gruppo')
gruppi_scheda = models.ForeignKey(Schede,on_delete = models.CASCADE, related_name = 'gruppi_scheda')
class Gruppi(models.Model):
nome_gruppo = models.CharField(max_length=100)
I have this tab where inside there are saved data groups that contain groups that are inside a select the correct exclusion would be
group_to_add = Gruppi.objects.exclude(dati_gruppo = 147)
but instead of 147 I have to put the id of the data group of that board
view
def creazione(request, nome):
scheda = get_object_or_404(Schede, nome_scheda = nome)
eserciziFormSet = formset_factory(EserciziForm, extra = 0)
if request.method == "POST":
gruppo_form = GruppiForm(request.POST, prefix = 'gruppo')
if gruppo_form.is_valid():
gruppo = gruppo_form.save(commit = False)
gruppo.gruppi_scheda = scheda
gruppoName = gruppo_form.cleaned_data['dati_gruppo']
gruppo.save()
esercizi_formset = eserciziFormSet(request.POST, prefix='esercizi')
for esercizi in esercizi_formset:
esercizi_instance = esercizi.save(commit = False)
esercizi_instance.gruppo_single = get_object_or_404(DatiGruppi, gruppi_scheda = scheda.id, dati_gruppo = gruppoName)
esercizi_instance.save()
return HttpResponseRedirect(request.path_info)
else:
group_to_add = Gruppi.objects.exclude(dati_gruppo = 147)
GruppiForm.base_fields['dati_gruppo'] = forms.ModelChoiceField(queryset = group_to_add)
gruppo_form = GruppiForm(prefix = 'gruppo')
esercizi_formset = eserciziFormSet(prefix='esercizi')
context = {'scheda' : scheda, 'gruppo_form' : gruppo_form, 'esercizi_formset': esercizi_formset}
return render(request, 'crea/passo2.html', context)
If I understand it correctly, you should use .exclude(…) [Django-doc] not .filter(…) [Django-doc]:
group_to_add = Gruppi.objects.exclude(
dati_gruppo__gruppi_scheda=scheda
)
GruppiForm.base_fields['dati_gruppo'] = forms.ModelChoiceField(queryset=group_to_add)
Related
look at the picture before answering me.
that group2 is inside saved in the db with the button I open a modal that allows me to save other groups in the db and I would like that the same groups no longer appear in that select if I have already added them
form.py
class EserciziForm(forms.ModelForm):
class Meta:
model = models.DatiEsercizi
exclude = ['gruppo_single']
#fields = '__all__'
class GruppiForm(forms.ModelForm):
class Meta:
model = models.DatiGruppi
exclude = ['gruppi_scheda']
views.py
def creazione(request, nome):
scheda = get_object_or_404(Schede, nome_scheda = nome)
eserciziFormSet = formset_factory(EserciziForm, extra = 0)
if request.method == "POST":
gruppo_form = GruppiForm(request.POST, prefix = 'gruppo')
if gruppo_form.is_valid():
gruppo = gruppo_form.save(commit = False)
gruppo.gruppi_scheda = scheda
gruppoName = gruppo_form.cleaned_data['dati_gruppo']
gruppo.save()
esercizi_formset = eserciziFormSet(request.POST, prefix='esercizi')
for esercizi in esercizi_formset:
esercizi_instance = esercizi.save(commit = False)
esercizi_instance.gruppo_single = get_object_or_404(DatiGruppi, gruppi_scheda = scheda.id, dati_gruppo = gruppoName)
esercizi_instance.save()
return HttpResponseRedirect(request.path_info)
else:
gruppo_form = GruppiForm(prefix = 'gruppo')
esercizi_formset = eserciziFormSet(prefix='esercizi')
context = {'scheda' : scheda, 'gruppo_form' : gruppo_form, 'esercizi_formset': esercizi_formset}
return render(request, 'crea/passo2.html', context
models.py
class DatiGruppi(models.Model):
giorni_settimana_scelta = [
("LUNEDI","Lunedì"),
("MARTEDI","Martedì"),
("MERCOLEDI","Mercoledì"),
("GIOVEDI","Giovedì"),
("VENERDI","Venerdì"),
("SABATO","Sabato"),
("DOMENICA","Domenica")
]
giorni_settimana = MultiSelectField(choices = giorni_settimana_scelta,default = '-')
dati_gruppo = models.ForeignKey(
Gruppi,on_delete = models.CASCADE, related_name = 'dati_gruppo')
gruppi_scheda = models.ForeignKey(Schede,on_delete = models.CASCADE, related_name = 'gruppi_scheda')
class Schede(models.Model):
nome_scheda = models.CharField(max_length=100)
data_inizio = models.DateField()
data_fine = models.DateField()
utente = models.ForeignKey(User, on_delete = models.CASCADE,related_name = 'utente')
You can override a form field before instantiate it like this :
views.py
from django import forms
if request.method == "POST":
# Post logic here
else:
# We try to retrieve group that the current user is not yet in.
# Not your logic, but to sum up, you have to retrieve the groups
# which had not yet been added.
# Use a filter that permit you to retrieve only groups which had not yet been added.
group_to_add = Group.objects.filter(...)
GruppiForm.base_fields['group_field'] = forms.ModelChoiceField(
queryset=group_to_add)
# Instantiate the form now
# In this form, the choices are only those contained in the group_to_add queryset
form = GruppiForm(prefix = 'gruppo')
I have the model League
class League(models.Model):
league = models.IntegerField(primary_key=True)
league_name = models.CharField(max_length=200)
country_code = models.ForeignKey("Country",null=True, on_delete=models.SET_NULL)
season = models.ForeignKey("Season", null=True,on_delete = models.SET_NULL, to_field = "season")
season_start = models.DateField(null = True) season_end = models.DateField(null = True)
league_logo = models.URLField(null = True) league_flag = models.URLField(null = True)
standings = models.IntegerField(null=True)
is_current = models.IntegerField(null=True)
I created objects from this model. After it i needed to add some additional fields to League model after adding those fields League object became so
class League(models.Model):
league = models.IntegerField(primary_key=True)
league_name = models.CharField(max_length=200)
country_code = models.ForeignKey("Country",null=True, on_delete=models.SET_NULL)
season = models.ForeignKey("Season", null=True,on_delete = models.SET_NULL, to_field = "season")
season_start = models.DateField(null = True) season_end = models.DateField(null = True)
league_logo = models.URLField(null = True) league_flag = models.URLField(null = True)
standings = models.IntegerField(null=True)
is_current = models.IntegerField(null=True)
cover_standings = models.BooleanField(null=True)
cover_fixtures_events = models.BooleanField(null=True)
cover_fixtures_lineups = models.BooleanField(null=True)
cover_fixtures_statistics = models.BooleanField(null=True)
cover_fixtures_players_statistics = models.BooleanField(null=True)
cover_players = models.BooleanField(null=True)
cover_topScorers = models.BooleanField(null=True)
cover_predictions = models.BooleanField(null=True)
cover_odds = models.BooleanField(null=True)
lastModified = models.DateTimeField(auto_now=True)
I did migrations and added these fields to db schema. Now i want to add to these added fields values. I read about
update_or_create method and tried to use it for updating League model objects
leagues_json = json.load(leagues_all)
data_json = leagues_json["api"]["leagues"]
for item in data_json:
league_id = item["league_id"]
league_name = item["name"] country_q =Country.objects.get(country = item["country"])
season = Season.objects.get(season = item["season"])
season_start = item["season_start"]
season_end = item["season_end"]
league_logo = item["logo"]
league_flag = item["flag"]
standings = item["standings"]
is_current = item["is_current"]
coverage_standings = item["coverage"]["standings"]
coverage_fixtures_events = item["coverage"]["fixtures"]["events"]
coverage_fixtures_lineups = item["coverage"]["fixtures"]["lineups"]
coverage_fixtures_statistics = item["coverage"]["fixtures"]["statistics"]
coverage_fixtures_plaers_statistics = item["coverage"]["fixtures"]["players_statistics"]
coverage_players = item["coverage"]["players"]
coverage_topScorers = item["coverage"]["topScorers"]
coverage_predictions = item["coverage"]["predictions"]
coverage_odds = item["coverage"]["odds"]
b = League.objects.update_or_create(league = league_id,
league_name = league_name,
country_code = country_q,season = season,
season_start = season_start,
season_end = season_end,
league_logo = league_logo,
league_flag = league_flag,
standings = standings,
is_current = is_current,
cover_standings = coverage_standings,
cover_fixtures_events = coverage_fixtures_events,
cover_fixtures_lineups = coverage_fixtures_lineups,
cover_fixtures_statistics= coverage_fixtures_statistics,
cover_fixtures_players_statistics = coverage_fixtures_players_statistics,
cover_players= coverage_players,
cover_topScorers = coverage_topScorers,
cover_predictions = coverage_predictions,
cover_odds = coverage_odds)
While i am trying to update objects by above method i get an error
django.db.utils.IntegrityError: duplicate key value violates unique constraint "dataflow_league_pkey"
DETAIL: Key (league)=(1) already exists.
I read about defaults argument of update_or_create method but didn't understand how to useit in my case. Can anyone help me
If you use update_or_create like this, first of all, your code will search the row in db with that all parameters.
I think you want to search league by league id and it works like this
You create the dict by any way of defaults, I just copy your code
defaults = dict(
league_name=league_name,
country_code=country_q,
season=season,
season_start=season_start,
season_end=season_end,
league_logo=league_logo,
league_flag=league_flag,
standings=standings,
is_current=is_current,
cover_standings=coverage_standings,
cover_fixtures_events=coverage_fixtures_events,
cover_fixtures_lineups=coverage_fixtures_lineups,
cover_fixtures_statistics=coverage_fixtures_statistics,
cover_fixtures_players_statistics=coverage_fixtures_players_statistics,
cover_players=coverage_players,
cover_topScorers=coverage_topScorers,
cover_predictions=coverage_predictions,
cover_odds=coverage_odds)
And use this defaults to update or create league with particular id
League.objects.update_or_create(defaults=defaults, league=league_id)
This code will find league with league_id and update it with data which you passed as the defaults parameter
OR
This code will create new league with that id and these params
You can use update_or_create like this
if exist, it return obj and created false
if not exist, it return obj and created true.
obj, created = League.objects.update_or_create(defaults=defaults, league=league_id)
I have models.py
class employees(models.Model):
emp_id=models.PositiveIntegerField()
emp_name = models.CharField(max_length = 100)
emp_lname = models.CharField(max_length = 100)
emp_loc=models.CharField(max_length=5,choices=LOCATION)
manager_id=models.ForeignKey('self',null=True,blank=True)
class leave(models.Model):
employee = models.ForeignKey(employees, on_delete=models.CASCADE, default='1')
start_date = models.DateField()
end_date = models.DateField()
status=models.CharField(max_length=1,choices=LEAVE_STATUS,default='P')
ltype=models.CharField(max_length=2,choices=LEAVE_TYPE)
message=models.CharField(max_length=500,blank=True)
class notify(models.Model):
sender_id=models.ForeignKey(leave, related_name='%(class)s_sendername')
receiver_id=models.ForeignKey(leave,related_name='%(class)s_receivername')
date_time=models.DateTimeField()
I have views.py
def accept(request):
approved_emp_id=leave.objects.filter(id=accept_id);
approving_emp_id=leave.objects.filter(employee__emp_id=request.user.username);
accept_notify=notify(sender_id=approving_emp_id, receiver_id=approved_emp_id,date_time=datetime.datetime.now(),viewed='N');
accept_notify.save()
When I want to save values to database I am getting error as ValueError: Cannot assign "<QuerySet [<leave: 121-geeta-2017-10-04-2017-10-06-C-V-2017-09-27 07:48:36.288873+00:00>]>": "notify.sender_id" must be a "leave" instance.
Where am I going wrong approving_emp_id and approved_emp_id are both leave instance only.
You are passing a QuerySet when the arguments should be an instance. A QuerySet is a list of instances. Pass only one instance. Use leave.objects.get() instead of leave.objects.filter().
objects.get() returns a single instance where objects.filter() returns a QuerySet.
def accept(request):
approved_emp_id = leave.objects.get(id = accept_id)
approving_emp_id = leave.objects.get(employee__emp_id = request.user.username)
accept_notify = notify(sender_id = approving_emp_id, receiver_id = approved_emp_id, date_time = datetime.datetime.now(), viewed = 'N')
accept_notify.save()
Another way is slicing the QuerySet.
def accept(request):
approved_emp_id = leave.objects.filter(id = accept_id)[0]
approving_emp_id = leave.objects.filter(employee__emp_id = request.user.username)[0]
accept_notify = notify(sender_id = approving_emp_id, receiver_id = approved_emp_id, date_time = datetime.datetime.now(), viewed = 'N')
accept_notify.save()
I am only creating entries for some fields in my models.py at the moment. Now I want to add Delete and Update functions to my Application. Let's take this Model for example:
class todoList(models.Model):
trainee = models.ForeignKey(trainee, verbose_name = "Azubi", blank = True)
todoLearningObjective = models.ManyToManyField(learningObjective, verbose_name = "Lernziel", blank = True, null = True)
tasks = models.TextField(verbose_name = 'Aufgaben')
levyDate = models.DateField(verbose_name = 'Abgabedatum', blank = True, null = True)
priority = models.IntegerField(verbose_name = 'Prioritaet', blank = True, null = True)
class Meta:
verbose_name = "To-Do Liste"
verbose_name_plural = "To-Do Listen"
The matching Form:
class todoListForm(forms.Form):
formtrainee = forms.IntegerField(required = False)
formtodoLearningObjective = forms.CharField(required = False)
formtasks = forms.CharField(required = True)
formlevyDate = forms.DateField(required = False)
formpriority = forms.IntegerField(required = False)
And the View:
def todo(request):
trainee_objects = trainee.objects.all()
usernameID = 1
for traineeUser in trainee_objects:
if traineeUser.username == request.user.username:
usernameID = traineeUser.id
if request.method == 'POST':
forms = todoListForm(request.POST)
if forms.is_valid():
formtasks = forms.cleaned_data['formtasks']
formtodoLearningObjective = forms.cleaned_data['formtodoLearningObjective']
formlevyDate = forms.cleaned_data['formlevyDate']
formpriority = forms.cleaned_data['formpriority']
neueTodo=todoList(tasks=formtasks, levyDate=formlevyDate, priority=formpriority, trainee_id = usernameID)
neueTodo.save()
for todo in learningObjective.objects.filter(learningObjectives=formtodoLearningObjective):
neueTodo.todoLearningObjective.add(todo)
else:
forms = todoList()
return render(request, 'todo.html', {'todo': todoList.objects.all(), 'Lernziel': learningObjective.objects.all()})
As you can see, I have M to M relations and I am just creating new entries. My question is now: Do I have to create a new update and delete method for every model ? Or is there an easier way ? I want to keep my project DRY although I probably failed that mission already. It would be awesome if you could give me example or documentation on how Deleting and Updating in Django works all in all.
You have built class based views for that.
from django.views.generic import CreateView,UpdateView,DeleteView
class Todo(CreateView):
formClass = todoListForm
template_name = 'your_template_name.html'
More information
I have a model :
class Certificate(models.Model):
comments = models.TextField(blank=True, default='')
generic_certificate = models.ForeignKey(GenericCertificate, related_name='certificates_awarded')
tag = models.ForeignKey('Tag', related_name='certificates_awarded', null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
history_timestamp = models.DateTimeField(auto_now=True)
rewardee = models.ForeignKey(OrganisationUser, related_name='certificates_rewarded')
position = models.CharField(max_length=50, default = '0,0')
I want to save position fields given primary-key.
Here is views.py :
def post(self, request , *args , **kwargs):
comments = Certificate.objects.values("comments").filter(pk = kwargs.get('cert_id') )
gen_certi = Certificate.objects.values("generic_certificate").filter(pk = kwargs.get('cert_id') )
tag = Certificate.objects.values("tag").filter(pk = kwargs.get('cert_id') )
history_timestamp = Certificate.objects.values("history_timestamp").filter(pk = kwargs.get('cert_id') )
rewardee = Certificate.objects.values("rewardee").filter(pk = kwargs.get('cert_id') )
position = request.POST.get('hid')
position = str([position])
a = Certificate.objects.create( comments=comments, generic_certificate = gen_certi , tag=tag,rewardee=rewardee, position=position )
print a
Its giving error :
Exception Value:
Cannot assign "[{'generic_certificate': 2}]": "Certificate.generic_certificate" must be a "GenericCertificate" instance.
Please help how to save position field into database.
gen_certi variable is a queryset (list of objects), because you are using filter() - use get() instead:
gen_certi = Certificate.objects.get(pk = kwargs.get('cert_id')).generic_certificate
Actually, I don't understand what are you planning to do in the view. If you are modifying the object, there is no need to overwrite the existing fields, just update the fields that are passed to the view in request.POST, like position:
try:
certificate = Certificate.objects.get(pk = kwargs.get('cert_id'))
certificate.position = request.POST.get('hid')
certificate.save()
except DoesNotExist:
# create new certificate
certificate = Certificate()
...
Hope that helps.