I create a Django form to create a template (that is an object) with some attributes. The user that want to create this template, obviously, should give a name to template.
I write clean name() method that checks if a template with that name already exists but now I want to create a method that shows an error message if the user does not provide a name for the template that he's creating. How can I do?
This is the django model for the templateForm with his fields:
class TemplateForm(BaseForm):
enabled_parameters = forms.CharField(widget=forms.HiddenInput())
name = forms.CharField(label=_("name *"))
sport = forms.CharField(label=_("sport"), widget=forms.TextInput(attrs={"readonly": "readonly"}))
owner = forms.CharField(label=_("owner"), widget=forms.TextInput(attrs={"readonly": "readonly"}))
visibility = forms.ChoiceField(label=_("visibility"), choices=Template.VISIBILITIES, widget=forms.RadioSelect())
last_update = forms.CharField(label=_("last update"), widget=forms.TextInput(attrs={"readonly": "readonly"}))
def clean_name(self):
"""check if template's name is unique"""
name = self.cleaned_data.get("name")
template_num = 0
if self.template.pk and name == self.template.name:
template_num = 1
if Template.objects.filter(name=name, team=self.template.team).count() != template_num:
raise ValidationError(_("A Template named {} already exists.".format(name)))
return name
Related
I've wrote this code:
views.py
if not null:
Address.objects.create(user = request.user,first_name = ad,last_name = soyad,address_title = baslik,address = adres,postalcode = posta,tel = gsm,il_ilce = Ilce.objects.get(il_id__il = sehir,ilce = ilce))
models.py
class Il(models.Model):
il = models.CharField(max_length=20,blank=False,null=False)
def __str__(self):
return str(self.il)
class Ilce(models.Model):
ilce = models.CharField(max_length=20,blank=False,null=False)
il_id = models.ForeignKey(Il,blank=False,null=False,on_delete=models.PROTECT)
def __str__(self):
return str(self.ilce)
class Address(models.Model):
first_name = models.CharField(max_length=30,blank=False,null=False)
last_name = models.CharField(max_length=30,blank=False,null=False)
user = models.OneToOneField(User,on_delete=models.CASCADE)
address_title = models.CharField(max_length=20,blank=False,null=False,default="Adres")
address = models.TextField(max_length=255,blank=False,null=False)
il_ilce = models.ForeignKey(Ilce,blank=False,null=False,on_delete=models.PROTECT)
postalcode = models.CharField(max_length=5,blank=False,null=False)
tel = models.CharField(max_length=11,blank=False,null=False)
def __str__(self):
return str(self.user) + '-' + str(self.address_title)
but I'm getting this error:
duplicate key value violates unique constraint "Users_address_user_id_key"
DETAIL: Key (user_id)=(1) already exists.
I don't want the code to create a new user object I want it to create a new address object only.
I don't want the code to create a new user object I want it to create a new address object only. - You've used OneToOneField in your Address model which means each user will have one address associated with it if you try to create one more then it will raise given exception duplicate key value violates unique constraint "Users_address_user_id_key" so to solve this you can use
update_or_create(...) [Djnago-doc] or If you want to use multiple address against one use then you've to change OneToOneFiled to ForeignKey.
I'm trying to work with severals objects to achieve an action.
My models.py
class LogBook(models.Model):
name = models.CharField()
class LogMessage(models.Model):
logbook = models.ForeignKey(LogBook, on_delete=models.CASCADE)
class LogDone(models.Model):
logmessage = models.ForeignKey(LogMessage)
done_status = models.BooleanField(default=False)
My view :
def logmessage_done(request, logmessage_id, log_id, token ):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log)
logdone = LogDone.objects.get_or_create(logmessage=logmessages)
logdone.done_status = True
logdone.update()
My url :
"done/<int:logmessage_id>/<int:log_id>/<str:token>"
What I want to achieve :
I want to change the status of the logdone object which is link to the logmessage object but I am not sure I have access object correctly.
What error I have :
The QuerySet value for an exact lookup must be limited to one result using slicing.
Change your view like this:
def logmessage_done(request, logmessage_id, log_id, token ):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log)
for log_message in logmessages:
LogDone.objects.update_or_create(logmessage=log_message,defaults={"done_status": True})
Here , log returns a single object with id . logmessages returns a queryset with logbook = the log returned in first query. Have to use update_or_create method
I have a project, where people will be able to create variables for a form, and then other users will fill that form. When they create the said form, they can chose the answer to be of 3 different types : From a list of value, an integer, or a string. Basically, I create a formset of all the variables the user created for this form, but if it is a list, I want to change the type of the input from a CharField to a ChoiceField.
So this is my view :
def insererDonnee(request, modele, contexte=-1):
variables = Variable.objects.filter(modele=modele)
varIter = variables.iterator()
DonneeFormSet = formset_factory(InsertDonneeForm, extra=variables.count())
submitAdress = "insererDonnee"
if request.POST:
formset = DonneeFormSet(request.POST)
else:
formset = DonneeFormSet()
for formx in formset:
formx.variable = varIter.next()
formx.nomVar = formx.variable.nom
formx.fields['valeur'].label = formx.nomVar
# Here I call setList to change the type
if formx.variable.type_variable in ["SOLIST", "LIST"]:
formx.setList(formx.variable)
And my form:
class InsertDonneeForm(forms.Form):
variable = Variable()
nomVar = 'Variable'
valeur = forms.CharField(label=nomVar, max_length=100)
def setList(self, variable):
choices = ListItem.objects.filter(variable=variable, modele=variable.modele)
valeur = forms.ModelChoiceField(queryset=choices)# or None)
print valeur
The last print was just to see if the field was indeed changed, which it is, but if I do the same print in my view after calling setList, my field are still
Is there anyways I could choose the appropriate type after creating the form?
Found the solution. The method setList, instead of changing the field directly in the form, now returns the new Choice field :
def setList(self, variable):
choices = ListItem.objects.filter(variable=variable, modele=variable.modele)
valeur = forms.ModelChoiceField(queryset=choices)
return valeur
And then in the view, I just have to assign the newly created field to the old field I want to change:
if formx.variable.type_variable in ["SOLIST", "LIST"]:
formx.fields['valeur']= formx.setList(formx.variable)
First of all: I am not able to find out the proper Title of this question.
Anyhow the question is:
I have to fill a form at template and the fields of this form are user dependent. For example you passes integer (integer is not a datatype) as a parameter to the method and it should returns like this:
fileds = forms.IntegerField()
If you pass bool then it should like this:
fields = forms.BooleanField()
So that i can use them to create my form. I tried with this code but it returns into the form of string.
Some.py file:
choices = (('bool','BooleanField()'),
('integer','IntegerField()'))
def choose_field():
option = 'bool' # Here it is hardcoded but in my app it comes from database.
for x in choices:
if x[0]==option:
type = x[1]
a = 'forms'
field = [a,type]
field = ".".join(field)
return field
When i print the field it prints 'forms.BooleanField()'. I also use this return value but it didn't work. Amy solution to this problem?
The simpliest way is to create your form class and include fields for all possible choices to it. Then write a constructor in this class and hide the fields you don't want to appear. The constructor must take a parameter indicating which fields do we need. It can be useful to store this parameter in the form and use it in clean method to correct collected data accordingly to this parameter.
class Your_form(forms.ModelForm):
field_integer = forms.IntegerField()
field_boolean = forms.BooleanField()
def __init__(self, *args, **kwargs):
option = kwargs["option"]
if option == "integer":
field_boolean.widget = field_boolean.hidden_widget()
else:
field_integer.widget = field_integer.hidden_widget()
super(Your_form, self).__init__(*args, **kwargs)
In your controller:
option = 'bool'
form = Your_form(option=option)
I have a model like below:
class StaffProfile(models.Model):
user = models.ForeignKey(User)
maas = models.FloatField()
maas_gunu = models.CharField(max_length=5)
When I try to insert data with a code like below:
staffprofilesay = StaffProfile.objects.filter(user = user_id).count()
if staffprofilesay > 0:
staffprofile = StaffProfile.objects.get(user = user_id)
else:
staffprofile = StaffProfile()
staffprofile.user = user_id
staffprofile.maas = calisan_formu.cleaned_data["maas"]
staffprofile.maas_gunu = calisan_formu.cleaned_data["maas_gunu"]
staffprofile.save()
I get an error like this:
Cannot assign "u'1'": "StaffProfile.user" must be a "User" instance.
What am I supposed to do?
PS: I'm using Django's User model
You need to assign a User object e.g.
from django.contrib.auth.models import User
user = User.objects.get(id=user_id)
staffprofile.user = user
user needs to be an instance of the User model, not a unicode object (which is what you are passing it).
Yes you have to pass User instance in staffprofile.user = user_id user id place.
As #david-s pointed out in a comment, if you don't have a user instance, you have to fetch from DB with an additional query.
Instead you can directly do is
staffprofile.user_id = user_id because Django behind the scene append _id in table for foreign keys so staffprofile.user will end staffprofile.user_id