Django form initial pass a list to one attribute - python

I met an issue when I want to pass a list of value to one attribute during initial the form.
The whole process of what I am doing is:
1. User defines a number N.
2. I display N text field.
3. User fills in data and I store in the database.
4. User wants to modify the data -> which is the issue I have when. I want to initial the form with current data.
Here is my model.py
class PageComponent(models.Model):
componentName=models.CharField(max_length=50,null=True, verbose_name="Name")
type = models.ForeignKey(Type, on_delete=models.CASCADE)
user = models.ForeignKey(AS_User, on_delete=models.CASCADE, editable=False)
page = models.ForeignKey(CommunityPage, on_delete=models.CASCADE, editable=False)
STATUS = (
('a', 'Activated'),
('d', 'Deactivated'),
)
componentStatus=models.CharField(
max_length=1,
choices=STATUS,
blank=False,
default='d',
help_text='the current status of the page component', editable=False
)
textContent=models.TextField(max_length=10000, help_text="Enter a description for your component", null=True, blank=True)
photoContent=models.ImageField(upload_to=component_directory_path, null=True, blank=True, verbose_name="Photo")
videoContent=models.FileField(upload_to=component_directory_path, null=True, blank=True, verbose_name="Video")
def __str__(self):
return self.componentName
class PageComponent_SeasonalText(models.Model):
pageStextComponent = models.ForeignKey(PageComponent, on_delete=models.CASCADE)
seasonalText = models.CharField(max_length=10001)
Here is my form.py
class SeasonalTextForm(forms.Form):
componentName = forms.CharField(label=_('Enter title'),max_length=40)
def __init__(self, *args, **kwargs):
seasonTexts = kwargs.pop('extra')
super(SeasonalTextForm, self).__init__(*args, **kwargs)
# self.cleaned_data = {}
for i in range(0, seasonTexts):
field_name = 'seasonText_%s' % (i,)
self.fields[field_name] = forms.CharField(widget=forms.Textarea(attrs={'rows':10, 'cols':51}))
#set field label as placeholder for every field
for field in self.fields.values():
field.widget.attrs["placeholder"] = field.label
def clean(self):
seasonTexts = set()
i = 0
field_name = 'seasonText_%s' % (i,)
while self.cleaned_data.get(field_name):
seasonText = self.cleaned_data[field_name]
if seasonText in seasonTexts:
self.add_error(field_name, 'Duplicate')
else:
seasonTexts.add(seasonText)
i += 1
field_name='seasonText_%s' % (i,)
self.cleaned_data["seasonTexts"] = seasonTexts
def save(self):
for seasonalText in self.cleaned_data["seasonTexts"]:
PageComponent_SeasonalText.objects.create(pageStextComponent = PageComponent.pageStextComponent,seasonalText = seasonalText,)
Here is my view.py
def edit_stext(request, page_id, id):
page = get_object_or_404(CommunityPage, pk=page_id)
component = PageComponent.objects.get(id=id)
stext = PageComponent_SeasonalText.objects.filter(pageStextComponent=component)
numOfSeasons = page.numSeasons
if request.method == "POST":
stextEditor = SeasonalTextForm(request.POST, instance=stext, extra=numOfSeasons)
if stextEditor.is_valid():
stextEditor.save()
return HttpResponseRedirect(reverse('page', kwargs={'page_id' : page_id}))
else:
# stext1 = PageComponent_SeasonalText.objects.filter(pageStextComponent=component)
initial = {}
initial['componentName'] = component.componentName
for i in range(0,numOfSeasons):
st = stext[i].seasonalText
print(st)
initial['seasonalText_{}'.format(i)] = st
stextEditor = SeasonalTextForm(initial=initial, extra=numOfSeasons)
return render(request, 'editComponent_stext.html', {'stextEditor': stextEditor})
NB:
at the view.py, I have a print function to print the actual value of the attribute "seasonalText" and it is success. But it seems cannot be passed to the initial when I want to initial the form.
Thanks for all spending time to help me with this issue. Many thanks.
Screenshot for understanding:
print function gets the correct value
initialed form doesn't get the seasonalText value

Related

Why am I getting core.Model.none?

I'm working on a django based backend.
I have a Submentor model. This model is going to have a list of names associated with it. So, I made a model called List. they both have a manytoMany relationship. Now, I made another model called names. This has a ManytoMany relationship with List. The list will have many names. Each Submentor will have one List each.
After coding when I try to add a value in The list from admin console I get core.Name.none instead of the name in my Submentors list.
What am I doing wrong?
code of models :-
class Names(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,blank=True,null=True)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class SAccepted_list(models.Model):
saccepted_name = models.ManyToManyField(Names,blank =True, related_name='saccepted_name')
def __str__(self):
return str(self.saccepted_name)
class SPending_list(models.Model):
spending_name = models.ManyToManyField(Names,blank =True, related_name='spending_name')
def __str__(self):
return str(self.spending_name)
class SRejected_list(models.Model):
srejected_name = models.ManyToManyField(Names,blank =True, related_name='srejected_name')
def __str__(self):
return str(self.srejected_name)
class SubMentor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
mentee_pref_count = models.IntegerField(default=3, verbose_name='Preferred mentee count')
rating = GenericRelation(Rating, related_query_name='Submentor')
skills = models.ManyToManyField(Skill, blank=True, related_name='subskills')
courses = models.ManyToManyField(Course, blank=True, related_name='subcourses')
projects = models.ManyToManyField(Project, blank=True, related_name='subprojects')
saccepted_list = models.ManyToManyField(SAccepted_list,blank=True,related_name='saccepted_list')
spending_list = models.ManyToManyField(SPending_list, blank=True,related_name='spending_list')
srejected_list = models.ManyToManyField(SRejected_list, blank=True,related_name='srejected_list')
def __str__(self):
return self.user.get_full_name()
def get_mentee_count(self, *args, **kwargs):
if self.trainees.exists():
return self.trainees.count()
else:
return 0
class Accepted_list(models.Model):
accepted_name = models.ManyToManyField(Names,blank =True, related_name='accepted_name')
# saccepted_name = models.ManyToManyField(Names,blank =True, related_name='saccepted_name')
def __str__(self):
return str(self.accepted_name)
class Pending_list(models.Model):
pending_name = models.ManyToManyField(Names,blank =True, related_name='pending_name')
# spending_name = models.ManyToManyField(Names,blank =True, related_name='spending_name')
def __str__(self):
return str(self.pending_name)
class Rejected_list(models.Model):
rejected_name = models.ManyToManyField(Names,blank =True, related_name='rejected_name')
# srejected_name = models.ManyToManyField(Names,blank =True, related_name='srejected_name')
def __str__(self):
return str(self.rejected_name)
class Mentor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
score = models.FloatField(default=0, blank=True, null=True)
mentee_pref_count = models.IntegerField(default=5, verbose_name='Preferred menteee count')
rating = GenericRelation(Rating, related_query_name='mentor')
skills = models.ManyToManyField(Skill, blank=True, related_name='skills')
accepted_list = models.ManyToManyField(Accepted_list,blank=True,related_name='accepted_list')
pending_list = models.ManyToManyField(Pending_list, blank=True,related_name='pending_list')
rejected_list = models.ManyToManyField(Rejected_list, blank=True,related_name='rejected_list')
def __str__(self):
return self.user.get_full_name()
def get_mentee_count(self, *args, **kwargs):
if self.trainees.exists():
return self.trainees.count()
else:
return 0
picture of me adding names direct through admin console:-
Thank you.
Ok, I solved my problem. It was wrong of me in the first place to use m2m and then another to make a list.
Instead I used only 1 m2m relationship with Lists and then made a property of them to be charfield. Now it's working properly.
Thanks :)

Manager object has no attribute 'save'

In my serializers.py I have a OrderCreateSerializer:
class OrderCreateSerializer(ModelSerializer):
data_params = serializers.DictField() # 根据产品数据模型不同而异
class Meta:
model = Order
fields = (
"product_describe", # 产品描述 (购买xx产品 + 参数)
"billing_type", # 计费类型 ("包年包月")
"data_params", # 数据
)
def create(self, validated_data):
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
validated_data["order_num"] = generateOrderNum(userid=user.id)
validated_data["order_status"] = "未支付"
validated_data["order_status"] = "未支付"
data_dic = validated_data.pop("data_params") #
# data_dic["data"]["profile"]
validated_data["buytime"] = data_dic["data"]["buytime"]
validated_data["count"] = data_dic["data"]["count"]
validated_data["paytype"] = ""
validated_data["cost"] = ""
validated_data["account"] = user.account
return Order.objects.save(**validated_data) # this is the line 57
When I save the validated_data, it report the bellow error:
Manager object has no attribute 'save'
My Order model is like bellow, there is many fields in it :
class Order(models.Model):
"""
订单
"""
order_num = models.CharField(max_length=128, unique=True) # 订单编号
order_status = models.CharField(max_length=12) # 订单状态 "未支付", "已支付,未完成", "已完成", "已经删除","其他"
product_describe = models.TextField() # 产品描述
billing_type = models.CharField(max_length=16) # 计费类型
buytime = models.CharField(max_length=16) # 比如:1月 永久
count = models.IntegerField() # 购买数量
paytype = models.CharField(max_length=16) # 支付方式(支付包,微信,xxx)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00) # 费用(需要花费多少钱)
account = models.ForeignKey(to=Account) # 所属账户
ctime = models.DateTimeField(auto_now_add=True) # 创建时间
uptime = models.DateTimeField(auto_now=True) # 更新时间
def __str__(self):
return self.product_describe
def __unicode__(self):
return self.product_describe
I don't know why there is the Manager object here.
You're calling save on the manager (ie, objects)
return Order.objects.save(**validated_data)
You call save on models.
I assume you're trying to create the model, in which case you want create.
return Order.objects.create(**validated_data)
Order.objects is an instance of the Manager class. The save method is a method of the model class.
Try:Order(**validated_data).save()

'QuerySet' object has no attribute ''cantidad_update"

how are you? I have this error when trying to subtract the values ​​in an IF where it is subtracted if the quantity_update is greater than 0. and if it does not subtract only the quantity.
models.py:
class Pedido(models.Model):
especialidad = models.ForeignKey('Especialidad')
articulo = models.ForeignKey('Articulo')
fecha_entrega = models.DateTimeField(auto_now_add=False, null=True, blank=True)
fecha_pedido = models.DateTimeField(auto_now_add=False,null=True, blank=True)
cantidad = models.IntegerField(blank=True, default=0)
estado = models.CharField(max_length=20, blank=True)
cantidad_update = models.IntegerField(blank=True, default=0)
estado_update = models.CharField(max_length=20, blank=True)
class Articulo(models.Model):
cod_experto = models.CharField(max_length=999, primary_key=True, blank=True)
nombre = models.CharField(max_length=999, blank=True)
on_delete=models.CASCADE)
stock = models.IntegerField(blank=True, default=0)
Views.py Query:
def Entregar(request, id_especialidad):
if request.method == 'GET':
especialidad = Especialidad.objects.get(id=id_especialidad)
pedido = Pedido.object.filter(especialidad=especialidad).filter(estado='pendiente')
if pedido.cantidad_update > 0: #Here is the error!
pedido.articulo.stock -= pedido.cantidad_update
else:
pedido.articulo.stock -= pedido.cantidad
pedido.save()
pedido2 = Pedido.objects.filter(especialidad=especialidad).filter(estado='pendiente').update(estado='entregado').update(fecha_entrega=datetime.date.today())
return HttpResponseRedirect('/solicitar/lista_super/%s/' % id_especialidad)
This would be relevant and I do not know that I'm missing, some help please!
Change
pedido = Pedido.object.filter(especialidad=especialidad).filter(estado='pendiente')
` to
pedido = Pedido.object.filter(especialidad=especialidad).filter(estado='pendiente')[0]
# or use for x in y to iterate each item`,
Your error occurs because filter() returns Queryset, not Pedido Object!
But in your case why are you using filter instead of get!
Using pedido = Pedido.object.filter(especialidad=especialidad).filter(estado='pendiente')[0] as long as there is data to retrieve. But when there is no data ? the query fails and the page returns 500 error. Because None queryset will not have 0th element.
Consider using get_object_or_404 since you want to get single object. Use something like which will be fail
def Entregar(request, id_especialidad):
if request.method == 'GET':
especialidad = get_object_or_404(Especialidad, id=id_especialidad)
pedido = get_object_or_404(Pedido, especialidad=especialidad, estado='pendiente')
if pedido.cantidad_update > 0: # Here is the error!
pedido.articulo.stock -= pedido.cantidad_update
else:
pedido.articulo.stock -= pedido.cantidad
pedido.save()
pedido2 = get_object_or_404(Pedido, especialidad=especialidad, estado='pendiente')
pedido2.update(estado='entregado').update(fecha_entrega=datetime.date.today())
return HttpResponseRedirect('/solicitar/lista_super/%s/' % id_especialidad)

Django: append a count of manytomany object instances and then retrieve it in template

Okay, so I'm sure i'm making a simple error here but I'm at a loss as to what it might be at this point or where to even begin to find the cause of this failing...
I have 5 models, set up like so:
class Keyword(models.Model):
key = models.CharField(max_length=2000, unique=True)
def __str__(self):
return self.key
class Entries(models.Model):
name = models.CharField("Name", max_length=200)
updated = models.DateTimeField("Last Updated", auto_now=True)
key_list = models.ManyToManyField(Keyword, blank=True, verbose_name="Keywords")
description = models.TextField("Description", blank=True)
class Meta:
abstract = True
class Employee(Entries):
uid= models.SlugField("UserID", max_length=6, unique=True, blank=True)
manager = models.SlugField("Manager's UserID", max_length=6)
def __str__(self):
return self.name
class Vendor(Entries):
company = models.CharField("Vendor Company", max_length=200)
email = models.EmailField("Vendor's Company Email Address", max_length=254, unique=True)
vend_man_name = models.CharField("Manager's Name", max_length=200)
vend_man_email = models.EmailField("Manager's Email Address", max_length=254)
def __str__(self):
return self.name
class Application(Entries):
app_url = models.URLField("Application URL", max_length=800, unique=True)
def __str__(self):
return self.name
class Machine(Entries):
address = models.CharField("Machine Address", max_length=800, unique=True)
phys_loc = models.TextField("Physical Location", blank=True)
def __str__(self):
return self.name
and my templatetag to display the data is thus:
#register.inclusion_tag('Labswho/key_cloud.html')
def key_cloud(keys_selected=''):
key_list = Keyword.objects.all()
for entry in key_list:
counter = Keyword.objects.filter(employee__key_list__key__contains=entry).distinct().count()
counter += Keyword.objects.filter(vendor__key_list__key__contains=entry).distinct().count()
counter += Keyword.objects.filter(application__key_list__key__contains=entry).distinct().count()
counter += Keyword.objects.filter(machine__key_list__key__contains=entry).distinct().count()
entry.append({'counter': counter})
context = {'key_list': key_list}
return context
but it keeps throwing me errors.
What I want it to do is to grab a count of the instances of each keyword on each model, add those instances together, and then give me a number I can reference in the template. My end goal is that I can use that number to set the font size so that keywords used more frequently will be visibly larger then ones used less frequently. I think what I want is for it to set a dictionary within each entry of my key_list, which i can then call for that number in the template when setting the font size. Not sure if i'm over-complicating this or how to fix it at this point so that it actually works...
(This is using Python 3.5 & Django 1.10)

Django populate a class model from command, working in DB but not showing on the page

So, the problem might be a bit too specific, I am not sure but I think I missed something in the way I fill my class in the commandBase.
And what I have at the moment is :
In the back office, in the sources / articles list everything is right. But in my page, articles parsed fro the .csv are not displayed.
Here is the model :
class Article(ModelMeta, TranslatableModel):
taints_cache = True
"""
Press article element,
"""
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
date_realization = models.DateField(_('Realised in'),
default=timezone.now)
image = FilerImageField(verbose_name=_('Featured image'), blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='image_press_article',
help_text=_('Set if the article will be featured'))
sources = models.ManyToManyField(ArticleSource, verbose_name=_('Source'),
blank=False, null=True, related_name='sources_press_article')
regions = models.ManyToManyField(Country, verbose_name=_('Country of the article'),
blank=True, null=True,
related_name='regions_press_article')
global_regions = models.BooleanField('Global', default=True)
featureArticle = models.BooleanField(_('Feature'), help_text=_('Feature this article'), default=False)
sites = models.ManyToManyField(Site, verbose_name=_('Sites'), blank=True,
null=True,
help_text=_('Select sites in which show the project.'))
article_url = models.CharField(_('Article Url'), max_length=310, blank=False,
help_text=_('Use to link to the original source'))
countries_displayed_in = models.ManyToManyField(
Country,
verbose_name=_('Countries displayed in'),
blank=True,
null=True,
related_name='displayed_in_press_article',
help_text='Select the countries in which this project will be visible.'
'If not selected, the project will be visible in all countries otherwise it will be'
'visible only for users that are located in the countries selected')
translations = TranslatedFields(
title=models.CharField(_('title'), max_length=510),
slug=models.SlugField(_('slug'), blank=False, db_index=True, max_length=300),
description=HTMLField(_('article description if featured'), default='', blank=True,
configuration='HTMLFIELD_CKEDITOR_SETTINGS_CONTENT'),
meta_description=models.TextField(verbose_name=_('article meta description'),
blank=True, default=''),
meta_keywords=models.TextField(verbose_name=_('article meta keywords'),
blank=True, default=''),
meta_title=models.CharField(verbose_name=_('article meta title'),
help_text=_('used in title tag and social sharing'),
max_length=255,
blank=True, default=''),
meta={'unique_together': (('language_code', 'slug'),)}
)
objects = ProjectManager()
_metadata = {
'title': 'get_title',
'description': 'get_description',
'keywords': 'get_keywords',
'locale': None,
'image': 'get_image_full_url',
'published_time': 'date_created ',
'modified_time': 'date_modified',
# Handle the get_absolute_url in the view to have access to the request
# and so, to the current_app namespace instance
# 'url': 'get_absolute_url',
}
def country(self):
return "\n".join(([p.name for p in self.regions.all()]))
def source(self):
return "\n".join([p.name for p in self.sources.all()])
def get_title(self):
title = self.safe_translation_getter('meta_title', any_language=True)
if not title:
title = self.safe_translation_getter('title', any_language=True)
return title.strip()
def get_keywords(self):
return self.safe_translation_getter('meta_keywords').strip().split(',')
def get_description(self):
description = self.safe_translation_getter('meta_description', any_language=True)
if not description:
description = self.safe_translation_getter('description', any_language=True)
return escape(strip_tags(description)).strip()
def get_image_full_url(self):
if self.image:
return self.image.url
return ''
class Meta:
verbose_name = _('Press article')
verbose_name_plural = _('Press articles')
get_latest_by = 'date_realization'
def __str__(self):
title = self.safe_translation_getter('title', any_language=True)
return title if title is not None else '(not translated)'
def save(self, *args, **kwargs):
if (self.article_url[:4] != "http") and (self.article_url[:5] != "https"):
self.article_url = "https://" + self.article_url
super(Article, self).save(*args, **kwargs)
main_lang = self.get_current_language()
for lang in self.get_available_languages():
self.set_current_language(lang)
if not self.slug and self.title:
self.slug = slugify(self.title)
self.set_current_language(main_lang)
self.save_translations()
def get_slug(self):
return self.safe_translation_getter(
'slug',
language_code=get_language(),
any_language=False)
And here is what I do in order to add my new articles, in the django command :
class Command(BaseCommand):
help = 'Import list of press article from .csv'
def handle(self, *args, **options):
ArticleFile = csv.reader(open(args[0]), delimiter=',')
global_article = ""
_country = ""
current_site = Site.objects.get_current()
for row in ArticleFile:
if row[0] != "Order":
if row[7] == "TRUE":
global_article = "True"
elif row[7] == "FALSE":
global_article = "False"
_source = ArticleSource.objects.create(name=row[5])
logging.info("\n\n URL: " + row[9] + "\n")
new_article = Article(
article_url=row[9],
global_regions=global_article,
title = row[8],
date_realization=datetime.strptime(row[4] + '-' + row[3] + '-' + row[2], '%Y-%m-%d').date(),
#sites=current_site,
)
new_article.save()
new_article.sources.add(_source)
new_article.sites.add(current_site)
logging.info("\n\n title: " + new_article.title)
if row[0] == "5":
break
When I check the DB and compare articles from the parsing and article added from the back-office, the only difference I noticed is the language.
For the ones added by hand it's :
"en" and for the ones from the .csv it's "en-us".
So it might be the problem but I am not sure.
And even if it is, I don't know how to "force it" to be 'en' instead of 'en-us'.
Does anyone has a clue about it ?
Am I doing it right ? It's the first time I parse a csv and populate and external model with python / django.
Many thanks.
Wow, so the language was the problem.
I found this :
from django.utils.translation import activate
I just had to add :
class Command(BaseCommand):
help = 'Import list of press article from .csv'
def handle(self, *args, **options):
activate('en')
To my code and now everything's displaying correctly !
By the way, I am still wondering if I am populated my class the right way.
Feel free to comment, I would love to learn !

Categories