我有一个如下所示的models.py文件:
from django.db import models
from common.models import Record
from tinymce import models as tinymce_models
# Create your models here.
class Address(Record):
def __unicode__(self):
return unicode(self.ip)
ip = models.IPAddressField(unique=True)
notes = models.TextField(blank=True)
class Meta:
verbose_name_plural = "Addresses"
class Servers(models.Model):
def __unicode__(self):
return unicode(self.server_name)
server_name = models.CharField(max_length=100)
ip_address = models.ForeignKey(Address)
secondary_ips = models.ManyToManyField(Address, verbose_name = 'Secondary IPs', blank=True, related_name='secondary_ips')
class Meta:
verbose_name_plural = "Servers"
我有一个系统中的IP和服务器列表。我试图让ManytoManyField只显示当前没有与服务器关联的IP列表。
我有以下查询集:
inner_qs = Servers.objects.values_list('ip_address_id', flat=True)
entries = Address.objects.exclude(id__in=inner_qs)
它仅返回不在Server表中的IP地址。我不知道如何将这些结果合并到我的ManytoManyField中以及我应该放置查询集的位置。我目前只在进入django Shell时获得结果
任何想法,
由于
答案 0 :(得分:5)
如果要将查询集添加到多对多字段,请先将其更改为列表,然后使用*
将其添加为位置参数实施例
# Returns a queryset
permissions = Permission.objects.all()
# Add the results to the many to many field (notice the *)
group = MyGroup.objects.get(name='test')
group.permissions.add(*permissions)
答案 1 :(得分:0)
您可以在此处使用此答案:Filter ManyToMany box in Django Admin
简而言之,您需要创建一个扩展django.forms.ModelForm
的自定义表单。在__init__
- 方法中,将新选项放置到正确的窗口小部件(secondary_ips
)。最后,将form = YourOwnForm
添加到您正在使用的ServerAdmin
类中。
我建议修改related_names
- 模型中的Servers
:
class Servers(models.Model):
# ...
ip_address = models.ForeignKey(Address, related_name='server')
secondary_ips = models.ManyToManyField(Address, verbose_name = 'Secondary IPs', \
blank=True, related_name='servers_secondary')
然后,您可以使用一个漂亮的QuerySet:
allowed_addresses = Address.objects.filter(server=None)
辅助地址
当然,这只过滤了某些服务器中作为主IP的IP。如果你想过滤掉在其他服务器上作为secondary_ip的ips,事情会变得有点棘手:
您还需要在servers_secondary=None
上进行过滤。但是您无法过滤掉为当前对象(在管理员中编辑的服务器)选择的IP,或者那些选定的IP也将消失。
使用Q objects完成此操作,并从kwargs
中抓取当前选定的对象。您的自定义表单的__init__
- 方法将如下所示:
def __init__(self, *args, **kwargs):
super(YourOwnForm, self).__init__(*args, **kwargs)
instance = kwargs.get('instance')
allowed_addresses = Address.objects \
.filter(server=None) \
.filter(Q(servers_secondary=None) | Q(servers_secondary=instance))
choices = []
for choice in allowed_addresses:
choices.append((choice.id, choice.ip))
w = self.fields['secondary_ips'].widget
w.choices = choices
主要地址下拉菜单
使用相同的方法,还可以过滤主IP地址下拉菜单中的项目。当然,必须注意不要从列表中删除所选的IP地址。
答案 2 :(得分:0)
返回查询集
POST
将结果添加到多对多字段(请注意permissions = Permission.objects.all()
)
*
答案 3 :(得分:0)
之所以到达这里,是因为我有一个模型,其中有一个指向该模型“ CampaignsProducts”的manytomanyfield,其 str 属性正在生成许多查询:
之前:
class CampaignsProducts(mdlcom.CommonStructure):
product = models.ForeignKey(
'products.Product',
verbose_name=u'Producto',
null=False, on_delete=models.CASCADE,
related_name="%(app_label)s_%(class)s_product_set",
)
campaign = models.ForeignKey(
'prices.Campaigns',
verbose_name=u'Campaña',
null=False, on_delete=models.CASCADE,
related_name="%(app_label)s_%(class)s_campaign_set",
)
def __str__(self):
return '{} - {}'.format(self.product.name, self.campaign.name)
为了修复它,我更改了以下“ str ”属性
def __str__(self):
return str(self.id)
和Mikko提供的解决方案挽救了我的生命:
class CouponForm(forms.ModelForm):
NO_REQUIRED = [
'sellers', 'platforms', 'campaigns_product',
]
class Meta:
model = mdlpri.Coupon
fields = '__all__'
def get_campaigns_choices(self):
qscampaigns = (
mdlpri.CampaignsProducts.objects.all()
.select_related("product")
.select_related("campaign")
.order_by("id")
)
choices = []
for item in qscampaigns:
wdescription = '{} - {}'.format(
item.product.name, item.campaign.name
)
choices.append((item.id, wdescription))
return choices
def __init__(self, *args, **kwargs):
super(CouponForm, self).__init__(*args, **kwargs)
for wfield in self.NO_REQUIRED:
self.fields[wfield].required = False
个性化选择
w = self.fields["campaigns_product"].widget w.choices = self.get_campaigns_choices()
更改前查询(按产品):
SELECT "products_product"."id", "products_product"."name", "products_product"."custom", "products_product"."created_at", "products_product"."updated_at", "products_product"."active", "products_product"."position", "products_product"."url", "products_product"."for_bonus_platform", "products_product"."for_cms_platform", "products_product"."for_store_platform", "products_product"."for_call_center_platform", "products_product"."for_ibk_platform", "products_product"."for_scotiabank_platform", "products_product"."for_bbva_platform", "products_product"."for_refurbished_platform" FROM "products_product" WHERE "products_product"."id" = 1
更改后查询:
SELECT "prices_campaignsproducts"."id", "prices_campaignsproducts"."date_created_at", "prices_campaignsproducts"."created_at", "prices_campaignsproducts"."updated_at", "prices_campaignsproducts"."user_id", "prices_campaignsproducts"."last_user_modified_id", "prices_campaignsproducts"."product_id", "prices_campaignsproducts"."campaign_id", "prices_campaignsproducts"."price", "prices_campaignsproducts"."is_active", "prices_campaignsproducts"."expiration_from", "prices_campaignsproducts"."expiration_to", "products_product"."id", "products_product"."name", "products_product"."custom", "products_product"."created_at", "products_product"."updated_at", "products_product"."active", "products_product"."position", "products_product"."url", "products_product"."for_bonus_platform", "products_product"."for_cms_platform", "products_product"."for_store_platform", "products_product"."for_call_center_platform", "products_product"."for_ibk_platform", "products_product"."for_scotiabank_platform", "products_product"."for_bbva_platform", "products_product"."for_refurbished_platform", "prices_campaigns"."id", "prices_campaigns"."date_created_at", "prices_campaigns"."created_at", "prices_campaigns"."updated_at", "prices_campaigns"."user_id", "prices_campaigns"."last_user_modified_id", "prices_campaigns"."name", "prices_campaigns"."is_active" FROM "prices_campaignsproducts" INNER JOIN "products_product" ON ("prices_campaignsproducts"."product_id" = "products_product"."id") INNER JOIN "prices_campaigns" ON ("prices_campaignsproducts"."campaign_id" = "prices_campaigns"."id") ORDER BY "prices_campaignsproducts"."id" ASC
只想分享我的经验。
最诚挚的问候,