The code I have is a pager that works for me very well, but now I would like to add the option to search but I do not know how to integrate it with my code, I appreciate all the help provided.
This is my url:
url(r'negocios/(?P<pagina>\d+)/$', NegociosView.as_view(),name='vista_negocios'),
This is my view:
class NegociosView(ListView):
def get(self, request, *args, **kwargs):
pagina = kwargs['pagina']
lista_negocios = Perfil.objects.all()
paginator = Paginator(lista_negocios,2)
try:
page = int(pagina)
except:
page = 1
try:
nego = paginator.page(page)
except(EmptyPage,InvalidPage):
nego = paginator.page(paginator.num_pages)
ctx = {'negocios':nego}
return render_to_response('home/negocios.html',ctx,context_instance=RequestContext(request))
This is my template code:
This is the view from the browser:
Try this
if request.GET.get('search'):
lista_negocios = Perfil.objects.filter(myfield=request.GET['search'])
else:
lista_negocios = Perfil.objects.all()
Then in url, access as
full_url/?search=search_string
Related
I'm working with Python 3.9 and Django 3.1.6. I have a quite long model in models.py. Short version is something like this:
class Check (models.Model):
#property
def total_body_fat_percentage(self):
if self.client_gender == "M":
total_body_fat_percentage = (self.Yuhasz * 0.097) + 3.64
pass
else:
total_body_fat_percentage = total_body_fat_percentage = float((self.Yuhasz * 0.1429) + 4.56)
return total_body_fat_percentage
#property
def muscle_weight_percentage(self):
muscle_weight_percentage =self.muscle_weight*100/self.weight
return muscle_weight_percentage
These fields return a float number. Something like 14.407.
Of course there are other fields in there such as Yuhasz, client_gender, etc.
I need these values into JSON. I tried to use the following serializer on serializer.py:
class PercentagesSerializer(ModelSerializer):
class Meta:
model = Check
fields = ('total_body_fat_percentage', 'muscle_weight_percentage')
And I have the following class on views.py:
class PercentagesAPI(APIView):
authentication_classes = []
permission_classes = []
serializer = PercentagesSerializer
def get(self, request, format=None):
lista = Check.objects.all()
print(lista)
response = self.serializer(lista)
print(response)
json_response= json.dumps(response.data)
print(json_response)
data = {
'percentages': json_response
}
return Response(response.data)
But it returns no data. Shell console states that it gets the queryset, it gets the fields, but it doesn't seems to get the values:
<QuerySet [<Check: Check object (1)>]>
PercentagesSerializer(<QuerySet [<Check: Check object (1)>]>):
total_body_fat_percentage = ReadOnlyField()
muscle_weight_percentage = ReadOnlyField()
{}
Thank you in advance for your advices and help!
You populate data variable but never use it. Instead you return response.data
response = self.serializer(lista)
data = {
'percentages': json_response
}
return Response(response.data)
I reckon this is the solution:
response = self.serializer(lista, many=True) # <-- many
data = {
'percentages': json_response
}
return Response(data) # <-- data
The query does return something - print shows 1 record/object: Check object (1)
I have a filter in django rest charfilterinfilter(field_name= 'genres__name', lookup_expr= 'in').I have in the database is which two categories to approach I through Many To Many did ,But I have when filtrating two categories of this product there are two elements I need only one element
views
class CharFilterInFilter(filters.BaseInFilter, filters.CharFilter):
pass
class ShoppFilter(filters.FilterSet):
price = filters.RangeFilter()
genres = CharFilterInFilter(field_name='genres__name')
title = SearchFilter()
class Meta:
model = smartphone
fields = ['price','genres','title']
class MDShopListView(generics.ListAPIView):
queryset = smartphone.objects.all()
filter_backends = (DjangoFilterBackend,SearchFilter)
search_fields = ['title']
filterset_class = ShoppFilter
def get(self, request):
queryset = self.filter_queryset(self.get_queryset())
serializer=MDShopListSerializer(queryset,many=True)
return Response(serializer.data)
models
genres = models.ManyToManyField(Genre, verbose_name="жанры")
class Genre(models.Model):
[enter image description here][1]
name = models.CharField("Имя", max_length=100)
img json
1: https://i.stack.imgur.com/4WR6L.png
here change and work
queryset = self.filter_queryset(self.get_queryset()).distinct()
class CharFilterInFilter(filters.BaseInFilter, filters.CharFilter):
pass
class ShoppFilter(filters.FilterSet):
price = filters.RangeFilter()
genres = CharFilterInFilter(field_name='genres__name', lookup_expr='in')
title = SearchFilter()
class Meta:
model = smartphone
fields = ['price','genres','title']
class MDShopListView(generics.ListAPIView):
queryset = smartphone.objects.all()
filter_backends = (DjangoFilterBackend,SearchFilter)
search_fields = ['title']
filterset_class = ShoppFilter
def get(self, request):
queryset = self.filter_queryset(self.get_queryset()).distinct()
serializer=MDShopListSerializer(queryset,many=True)
return Response(serializer.data)
This is a usual problem with ManyToMany fields, solution would be to apply a distinct method to the query:
class ShoppFilter(filters.FilterSet):
...your filter definition as it is now
def filter_queryset(self, request, queryset, view):
return super(ShoppFilter, self).filter_queryset(
request, queryset, view
).distinct()
I am using the YouTube Data API to create an object, but when I create a single object, it creates two objects - one with the proper details and one that is blank. How can I resolve this issue?
before creating object
after creating single object
I am trying with the following code.
view.py
class VideoCreateView(CreateView):
model = Video
form_class = VideoForm
template_name = "videos/video_form.html"
def form_valid(self, form):
video = Video()
video.url = form.cleaned_data['url']
parse = urllib.parse.urlparse(video.url)
video_id = urllib.parse.parse_qs(parse.query).get('v')
if video_id:
video.youtube_id =video_id[0]
response = requests.get(f'https://youtube.googleapis.com/youtube/v3/videos?part=snippet&id={video_id[0]}&key={YOUTUBE_API_KEY}')
json = response.json()
items = json["items"]
assert len(items) <= 1
if len(items):
title = items[0]["snippet"]["title"]
video.title = title
video.save()
else:
title = "N/A"
return super().form_valid(form)
models.py
class Video(models.Model):
title = models.CharField(max_length=255)
url = models.URLField()
youtube_id = models.CharField(max_length=255)
slug = models.SlugField(blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("videos:video_detail", kwargs={"slug":self.slug})
def video_pre_save_reciever(sender,instance,*args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(video_pre_save_reciever,Video)
if more code is require than tell me in comment , i will update my question with that information.
The view VideoCreateView inherits CreateView. CreateView inherits ModelFormMixin which defines form_valid method.
def form_valid(self, form):
"""If the form is valid, save the associated model."""
self.object = form.save()
return super().form_valid(form)
You save the video object and call the super form_valid which saves the form(in turn creating a model object) again. Hence, causing a double creation. I suggest modifying the form and passing it to super instead of manually saving it.
Another option is to inherit the View with django.views.generic.View. This would avoid form save.
I suggest you follow the first approach.
I have solve this my problem by removing all the form_valid code from the views and add that inside the model
class Video(models.Model):
title = models.CharField(max_length=255)
url = models.URLField()
youtube_id = models.CharField(max_length=255)
slug = models.SlugField(blank=True)
def save(self,*args,**kwargs):
parse = urllib.parse.urlparse(self.url)
video_id = urllib.parse.parse_qs(parse.query).get('v')
if video_id:
self.youtube_id =video_id[0]
response = requests.get(f'https://youtube.googleapis.com/youtube/v3/videos?part=snippet&id={video_id[0]}&key={YOUTUBE_API_KEY}')
json = response.json()
title = json["items"][0]["snippet"]["title"]
self.title = title
super(Video,self).save(*args,**kwargs)
I have this application where I want to deploy some web interface to a syslog server.
So the syslogserver does write his stuff into a mysql database. I already have build
some parts for the application except for this specific part where I want to build a dropdown select form, to select the hosttables inside the database.
Actually I am using flask, flask-sqlalchemy and wtforms. So I tried to implement this over the 'QuerySelectField', somehow I only get a dropdown with no table name entries shown.
I should mention that the tables inside the database itself are created on the fly. For my model I used the automap_base() Feature from sqlalchemy:
model.py
Base = automap_base()
engine = create_engine("mysql://sumuser:tehpass#127.0.0.1/syslog")
Base.prepare(engine, reflect=True)
session = Session(engine)
This is whats inside my forms:
forms.py
def factoryHelper():
return session.query("information_schema.tables.table_name from information_schema.tables where information_schema.tables.table_name like 'messages_hostname0'")
class HostSelectForm(Form):
title = TextField('Fooblah')
hostTables = QuerySelectField(query_factory=factoryHelper,allow_blank=True)
and this inside the views:
views.py
#app.route('/index/', defaults={'page':1})
#app.route('/index/page/<int:page>')
def index(page):
form = HostSelectForm()
count = session.execute("select host,facility,level,msg from messages_hostname0").rowcount
pagination = Pagination(page, PER_PAGE, count)
return render_template('index.html', pagination=pagination, form=form)
So is there anyway I can create a dropdown menu from dynamically created table names? Also if I use the automap feature? Thanks in advance.
Somehow i managed to solve this issue with this in the model.py:
def reflectTables():
for i in Base.classes.items():
yield i[0]
def stripTables():
tablelist = []
datelist = []
re0 = r"^(?P<prefix>[a-zA-Z]*)\_(?P<mid>[a-zA-Z,0-9]*)\_(?P<suffix>[0-9]*)"
myre = re.compile(re0, re.MULTILINE)
for x,table in enumerate(reflectTables()):
striptablename = re.match(myre, table.strip("\n"))
if striptablename:
tablelist.append((x, striptablename.group(2)))
datelist.append((x, striptablename.group(3)))
return dicht(tablelist,datelist)
the forms.py:
AVAILABLE_CHOICES = stripTables()
class HostSelectForm(Form):
tableSelect = SelectField('LogHost', choices=AVAILABLE_CHOICES, default=0)
and finnaly inside the views.py:
if request.method == "GET":
count = session.query("* from mytable_monitory_counts")
items = session.execute("select * from mytable_%s_%s limit %s, %s" % \
(tableslector[int(request.values['tableSelect'])][1],\
datelist[int(request.values['tableSelect'])][1], my_start_range, PER_PAGE)).fetchall()
pagination = Pagination(page=page, total=count.count(), search=search, record_name='hosts')
if not items and page != 1:
in_error()
return render_template('index.html', pagination=pagination, form=form, items=items)
I have a text area in a django based website that displays the content of a database field.
I'd like to be able to edit this field and submit it to a function which updates the field in the database.
I know how I can call a function in a views.py which then send back the result of the query using render_to_response to a new webpage.
So in summary, how do I adress a function in a django/python script using a html form without the need to refer to another url?
It's usually recommended to use Post/Redirect/Get pattern, for example:
def myview(request, **kwargs):
if request.POST:
# validate the post data
if valid:
# save and redirect to another url
return HttpResponseRedirect(...)
else:
# render the view with partial data/error message
if request.GET:
# render the view
return render_to_response(...)
Use AJAX:
1) Create a view to handle form submission:
def my_ajax_form_submission_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# save data or whatever other action you want to take
resp = {'success': True}
else:
resp = {'success': False}
return HttpResponse(simplejson.dumps(resp), mimetype='application/json')
else:
return HttpResponseBadRequest()
Then, tie the view into your urlpatterns
2) Submit form via AJAX (uses jQuery):
$('#my-form-id').submit(function(){
var $form = $(this);
$.post('/url/to/ajax/view/', $form.serialize(), function(data, jqXHR){
if (data.success) {
alert('Form submitted!');
} else {
alert('Form not valid');
}
});
return false;
});
That's the basics. You can and should provide more detailed return responses, error handling, form validation/checking, etc.
This is the standard views code pattern that I've been using.
def payment_details(request, obj_id):
yourobj = get_object_or_404(Obj, pk=obj_id)
form = TheForm(instance=yourobj)
if request.method == 'POST':
form = TheForm(request.POST, instance=yourobj)
if form.is_valid():
yourobj = form.save()
messages.success(request, 'Yourobj is saved!')
url = reverse('SOMEURL')
return redirect(url)
template = 'SOMETEMPLATE'
template_vars = {'TEMPLATEVARS': TEMPLATEVARS}
return render(request, template, template_vars)
Having watched the Advanced Forms talk at DjangoCon, one could re-write the above view like this:
def payment_details(request, obj_id):
yourobj = get_object_or_404(Obj, pk=obj_id)
form = TheForm(request.POST or NONE, instance=yourobj)
if request.method == 'POST' and form.is_valid():
yourobj = form.save()
messages.success(request, 'Yourobj is saved!')
url = reverse('SOMEURL')
return redirect(url)
template = 'SOMETEMPLATE'
template_vars = {'TEMPLATEVARS': TEMPLATEVARS}
return render(request, template, template_vars)